diff --git a/.gitignore b/.gitignore
index 210eb0b0..7ea1dbd0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,49 +1,11 @@
-secrets.txt
-*.pstore
-*.gem
-*.rbc
-*.swp
-.bundle/*
-.DS_Store
-.idea/*
-.loadpath
-.project
-.ruby-gemset
-.ruby-version
-/.bundle
-/.bundle/
-/.yardoc/
-/_yardoc/
-/coverage/
-/coverage/
-*.sqlite3
-*.sqlite3-journal
-/doc/
-/InstalledFiles
-/lib/.build
-/lib/bundler/man/
-/log/*.log
-*.log
-/pkg/
-/rdoc/
-/spec/reports/
-/test/tmp/
-/test/version_tmp/
-/tmp
-/tmp/
-config.yml
-coverage/**
-credentials.yml
-db/settings.yml
-doc/*
-doc/**/*
-log/*
-notes.rb
-/lib/.build
-write_db_settings.rb
-snippet.coffee
-snippets.rb
-tmp/**/*
-*.rb~
-serial_port.txt
-*credentials*
+# App artifacts
+/_build
+/db
+/deps
+/*.ez
+
+# Nerves images
+/_images
+
+# Generate on crash by the VM
+erl_crash.dump
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 4ea764e5..00000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1 +0,0 @@
-To get started, sign the Contributor License Agreement.
diff --git a/Gemfile b/Gemfile
deleted file mode 100644
index 8f6afd44..00000000
--- a/Gemfile
+++ /dev/null
@@ -1,19 +0,0 @@
-source 'https://rubygems.org'
-
-gem 'eventmachine', '1.2.0.1'
-gem 'active_record_migrations'
-gem 'farmbot-resource', '0.6.0' # REST API client for farmbot.
-gem 'farmbot-serial', '1.1.2' # Arduino communication.
-gem 'god' # For autorestarting on crashes and stuff.
-gem 'ice_cube' # For scheduling of pre-programmed schedule
-gem 'liquid' # For custom programming of schedules.
-gem 'mutations', '0.7.2' # for e-v-e-r-y-t-h-i-n-g
-gem 'settingslogic' # For settings.yml file
-gem 'highline' # For setup.rb.
-gem 'sqlite3' # For storing schedule data locally.
-gem 'em-mqtt', '~> 0.0.5' # For browser <--> device communication.
-
-group :test, :development do
- gem 'rspec'
- gem 'simplecov'
-end
diff --git a/Gemfile.lock b/Gemfile.lock
deleted file mode 100644
index 5e1cdfa1..00000000
--- a/Gemfile.lock
+++ /dev/null
@@ -1,139 +0,0 @@
-GEM
- remote: https://rubygems.org/
- specs:
- actionpack (4.2.3)
- actionview (= 4.2.3)
- activesupport (= 4.2.3)
- rack (~> 1.6)
- rack-test (~> 0.6.2)
- rails-dom-testing (~> 1.0, >= 1.0.5)
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (4.2.3)
- activesupport (= 4.2.3)
- builder (~> 3.1)
- erubis (~> 2.7.0)
- rails-dom-testing (~> 1.0, >= 1.0.5)
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
- active_record_migrations (4.2.3.1)
- activerecord (= 4.2.3)
- railties (= 4.2.3)
- rake
- activemodel (4.2.3)
- activesupport (= 4.2.3)
- builder (~> 3.1)
- activerecord (4.2.3)
- activemodel (= 4.2.3)
- activesupport (= 4.2.3)
- arel (~> 6.0)
- activesupport (4.2.3)
- i18n (~> 0.7)
- json (~> 1.7, >= 1.7.7)
- minitest (~> 5.1)
- thread_safe (~> 0.3, >= 0.3.4)
- tzinfo (~> 1.1)
- arel (6.0.3)
- builder (3.2.2)
- diff-lcs (1.2.5)
- docile (1.1.5)
- domain_name (0.5.20160310)
- unf (>= 0.0.5, < 1.0.0)
- em-mqtt (0.0.5)
- eventmachine
- mqtt (>= 0.3.0)
- erubis (2.7.0)
- eventmachine (1.2.0.1)
- farmbot-resource (0.6.0)
- rest-client (~> 1.8)
- farmbot-serial (1.1.2)
- eventmachine
- serialport
- god (0.13.6)
- highline (1.7.8)
- http-cookie (1.0.2)
- domain_name (~> 0.5)
- i18n (0.7.0)
- ice_cube (0.13.0)
- json (1.8.3)
- liquid (3.0.6)
- loofah (2.0.2)
- nokogiri (>= 1.5.9)
- mime-types (2.99.1)
- mini_portile (0.6.2)
- minitest (5.8.0)
- mqtt (0.3.1)
- mutations (0.7.2)
- activesupport
- netrc (0.11.0)
- nokogiri (1.6.6.2)
- mini_portile (~> 0.6.0)
- rack (1.6.4)
- rack-test (0.6.3)
- rack (>= 1.0)
- rails-deprecated_sanitizer (1.0.3)
- activesupport (>= 4.2.0.alpha)
- rails-dom-testing (1.0.6)
- activesupport (>= 4.2.0.beta, < 5.0)
- nokogiri (~> 1.6.0)
- rails-deprecated_sanitizer (>= 1.0.1)
- rails-html-sanitizer (1.0.2)
- loofah (~> 2.0)
- railties (4.2.3)
- actionpack (= 4.2.3)
- activesupport (= 4.2.3)
- rake (>= 0.8.7)
- thor (>= 0.18.1, < 2.0)
- rake (10.4.2)
- rest-client (1.8.0)
- http-cookie (>= 1.0.2, < 2.0)
- mime-types (>= 1.16, < 3.0)
- netrc (~> 0.7)
- rspec (3.3.0)
- rspec-core (~> 3.3.0)
- rspec-expectations (~> 3.3.0)
- rspec-mocks (~> 3.3.0)
- rspec-core (3.3.2)
- rspec-support (~> 3.3.0)
- rspec-expectations (3.3.1)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.3.0)
- rspec-mocks (3.3.2)
- diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.3.0)
- rspec-support (3.3.0)
- serialport (1.3.1)
- settingslogic (2.0.9)
- simplecov (0.10.0)
- docile (~> 1.1.0)
- json (~> 1.8)
- simplecov-html (~> 0.10.0)
- simplecov-html (0.10.0)
- sqlite3 (1.3.10)
- thor (0.19.1)
- thread_safe (0.3.5)
- tzinfo (1.2.2)
- thread_safe (~> 0.1)
- unf (0.1.4)
- unf_ext
- unf_ext (0.0.7.2)
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- active_record_migrations
- em-mqtt (~> 0.0.5)
- eventmachine (= 1.2.0.1)
- farmbot-resource (= 0.6.0)
- farmbot-serial (= 1.1.2)
- god
- highline
- ice_cube
- liquid
- mutations (= 0.7.2)
- rspec
- settingslogic
- simplecov
- sqlite3
-
-BUNDLED WITH
- 1.12.5
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..be1d84d3
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,9 @@
+The MIT License
+
+Copyright (c) 2016 Farmbot Project
+
+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/README.md b/README.md
index 03423c85..7fade835 100644
--- a/README.md
+++ b/README.md
@@ -1,137 +1,68 @@
-# FarmBot Software for the Raspberry Pi
+# FarmBot Software for the RaspBerry Pi 3
+The "brains" of Farmbot. Responsible for receiving the commands from users or the farmbot-web-app. It executes them and reports back the results to any subscribed user(s).
-The "brains" of Farmbot. Responsible for receiving the commands from users or the farmbot-web-app. It executes them and report back the results to any subscribed user(s).
+## Technical Stuff
+* Written in Elixir with the Nerves Framework
+* Operation scheduling is not working yet
+* Device status infor, such as X,Y,Z and calibration data is stored on the Data partition Nerves allows.
+* Backups to the cloud provided by ["Farmbot Web API"]("https://github.com/farmbot/farmbot-web-api")
+* Messaging happens vie ["MQTT"]("https://github.com/farmbot/mqtt-gateway")
-Technical Stuff
----------------
+# Running in production
+You can download the latest release from ["Here"]("https://github.com/FarmBot/farmbot-raspberry-pi-controller/releases")
+Make sure you download the `.img` file.
+## Windows users
+* You can use ["Win32 Disk Imager"]("https://sourceforge.net/projects/win32diskimager/")
+* Select the `.img` file you downloaded
+* Select your sdcard's drive letter
+* Click `write`
-* Written in Ruby.
-* Operation scheduling data is stored in SQLite 3.
-* Device status info, such as X, Y, Z and calibration data is stored via [PStore](http://ruby-doc.org/stdlib-1.9.2/libdoc/pstore/rdoc/PStore.html)
-* Backups to the cloud provided by [Farmbot Web API](https://github.com/farmbot/farmbot-web-api).
-* Messaging happens via [MQTT](http://mqtt.org/).
-* Communicates with Arduino hardware using the [farmbot-serial gem](https://github.com/FarmBot/farmbot-serial)
+## Linux / OSX / UNIX
+* `dd if=img_file of=/dev/sdX`
+* where img_file is the path to you `.img` file, and X is your device's drive letter.
-Running in production
----------------------
+## Running
+* Plug your SD Card into your RPi3
+* Plug your Arduino into your RPi3
+* Plug your power into your RPi3
+* From a WiFi enabled device, search for the SSID `FarmbotConfigurator`
+* Connect to that and open a web browser to ["http://192.168.24.1/"]("http://192.168.24.1")
+* Follow the on screen instruction
+* Profit???
-```
-bundle install
-ruby farmbot.rb
+# Building
+Ok its actually really easy once your environment is set up. Let me prefix this with this simple phrase. ["YOU NEED LINUX"]("http://www.whylinuxisbetter.net/") I am sorry. It is just the bottom line. A VM works fine, a dual boot environment works. even OpenSuse works. But `bash for windows` does not work. `Cygwin` does not work. and for the love of all things development ready, `osx` does not work. You need Linux to build Linux. So with that rant out of the way, and ready for revision here are the steps to build:
+* Install Elixir and Erlang. (Shameless plug for ASDF) ([HEY TRY ME?]("https://gist.github.com/ConnorRigby/8a8bffff935d1a43cd74c4b8cf28a845"))
+* install [`Nerves`]("https://hexdocs.pm/nerves/installation.html") (and all the things it tells you to install there)
+* clone and cd into this directory.
+* plug an sdcard into your machine.
+``` bash
+MIX_ENV=prod mix deps.get
+MIX_ENV=prod mix firmware
+MIX_ENV=prod mix firmware.burn
```
-
-Running on Local
-----------------
-
-If you're running your own local [farmbot web app](https://github.com/farmbot/farmbot-web-app)
-
-`FBENV=development ruby farmbot.rb`
-
-
-Installation on Raspberry Pi
-----------------------------
-
-Installation on a Raspberry Pi 3 will take about 30 minutes.
-
-### Update the RPi
-
-```
-sudo apt-get update
+You can also run locally (not on an RPI3) (This works on windows)
+``` bash
+export MIX_ENV=dev
+rm -rf _deps build _images
+mix deps.get
+iex -S mix
```
+You should only need to do the first two commands once.
-### Install Ruby 2.2
+## Debugging on hardware
+The Rpi will boot up with an Iex console on the hardware UART. If you need to debug something this is the easiest to get too.
+If you do not happen to have a 3.3v FTDI cable, you can build the firmware with the console on HDMI. In the `erlinit.config` file you can change `-c ttyS0` to `-c ttyS1`. This requires you to plug a usb mouse, keyboard and monitor into your pi.
-This gem requires Ruby 2.2 minimum. Later versions will work fine as well. As of this writing, a Pi is loaded with 1.9.3 by default.
+## Other stuff
+You can connect IEx to the running pi by doing
+`iex -name console@localhost --remsh farmbot@ --cookie democookie`
+Debug message still only will print to UART or HDMI (whichever you have configured)
-To remove the old version of Ruby that comes with most RPi distributions:
+If you are frequently building firmware, removing the sdcard and writing the build every time gets pretty old. You can upload firmware to an already running farmbot one of two ways after you run a successful `mix firmware`
+0. You can upload the image to the pi using CURL or similar. `curl -T _images/rpi3/fw.fw "http://$RPI_IP_ADDRESS:8988/firmware" -H "Content-Type: application/x-firmware" -H "X-Reboot: true"`
+0. Or you can host the .fw file on your pc using a webserver ie `npm install serve` and download it from the pi.This should be ran ON THE PI ITSELF `Downloader.download_and_install_update("http:///WHEREVER YOUR FILE IS")`
-```
-sudo apt-get remove ruby* --purge
-```
-
-To upgrade your ruby version, try this:
-
-```
-gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
-curl -L https://get.rvm.io | bash -s stable --ruby
-```
-
-This will take about 2 hours a standard Raspberry Pi 2, or about 20 minutes on a Raspberry Pi 3.
-
-### Clone, install and run
-
-**NOTE:** We tag releases when they are stable. The latest version (on master) is not guaranteed to be stable.
-
-See [releases](https://github.com/FarmBot/farmbot-raspberry-pi-controller/releases) to find a stable release.
-
-**OPTION A:** For less stable "edge" version:
-
-```
-git clone https://github.com/FarmBot/farmbot-raspberry-pi-controller
-```
-
-**OPTION B:** For stable release 1.1:
-
-```
-git clone -b 'alpha-1.1' --single-branch https://github.com/FarmBot/farmbot-raspberry-pi-controller
-```
-
-**REQUIRED FOR EITHER:** (takes about 10 minutes on an RPi 3)
-
-```
-cd farmbot-raspberry-pi-controller
-gem install bundler
-bundle install
-rake db:setup
-```
-
-#### Set up the device:
-
-Go to the [My Farmbot Website](http://my.farmbot.io) (or your private server) and sign up for a Farmbot account.
-
-Then from within the `farmbot-raspberry-pi-controller` project directory run:
-
-```bash
-ruby setup.rb
-```
-
-#### Report problems:
-
-We can't fix issues we don't know about. If you are having issues with setup, please [raise an issue with us](https://github.com/FarmBot/farmbot-raspberry-pi-controller/issues/new). This helps us identify confusing steps, common setup issues and other problems.
-
-Arduino
--------
-
-You will need to flash your Arduino with custom firmware. For instructions on how to do this, see [the FarmBot-Arduino github page](https://github.com/FarmBot/farmbot-arduino-firmware)
-
-Contributors
--------
-
-See full list [here](https://github.com/FarmBot/farmbot-raspberry-pi-controller/graphs/contributors).
-
-License
--------
-
-The MIT License
-
-Copyright (c) 2016 Farmbot Project
-
-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.
+# Tests
+Test coverage is not very good right now but you should be able to run `mix test --no-start` and see tests run.
diff --git a/Rakefile b/Rakefile
deleted file mode 100644
index 6cd88fab..00000000
--- a/Rakefile
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'active_record_migrations'
-
-ActiveRecordMigrations.configure do |c|
- c.database_configuration = {
- 'development' => {'adapter' => 'sqlite3',
- 'database' => 'db/db.sqlite3'},
- }
-end
-
-ActiveRecordMigrations.load_tasks
diff --git a/VERSION b/VERSION
new file mode 100644
index 00000000..227cea21
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+2.0.0
diff --git a/config/config.exs b/config/config.exs
new file mode 100644
index 00000000..a7be61a8
--- /dev/null
+++ b/config/config.exs
@@ -0,0 +1,2 @@
+use Mix.Config
+import_config "#{Mix.env}.exs"
diff --git a/config/dev.exs b/config/dev.exs
new file mode 100644
index 00000000..10e0ea86
--- /dev/null
+++ b/config/dev.exs
@@ -0,0 +1,9 @@
+use Mix.Config
+config :uart,
+ baud: 115200
+
+config :fb,
+ ro_path: "/tmp"
+
+config :json_rpc,
+ transport: MqttHandler
diff --git a/config/prod.exs b/config/prod.exs
new file mode 100644
index 00000000..4fe2ef34
--- /dev/null
+++ b/config/prod.exs
@@ -0,0 +1,14 @@
+use Mix.Config
+config :nerves, :firmware,
+ rootfs_additions: "config/rootfs-additions-#{Mix.Project.config[:target]}",
+ hardware: "config/rootfs-additions-#{Mix.Project.config[:target]}"
+
+config :uart,
+ baud: 115200
+
+config :fb,
+ ro_path: "/root",
+ update_server: "http://192.168.29.154:4040"
+
+config :json_rpc,
+ transport: MqttHandler
diff --git a/config/rootfs-additions-rpi3/etc/erlinit.config b/config/rootfs-additions-rpi3/etc/erlinit.config
new file mode 100644
index 00000000..c5d350a8
--- /dev/null
+++ b/config/rootfs-additions-rpi3/etc/erlinit.config
@@ -0,0 +1,41 @@
+
+# Additional configuration for erlinit
+
+# Turn on the debug prints
+#-v
+
+# Specify the UART port that the shell should use.
+-c ttyS0
+
+# If more than one tty are available, always warn if the user is looking at
+# the wrong one.
+--warn-unused-tty
+
+# Use dtach to capture the iex session so that it can be redirected
+# to the app's GUI
+#-s "/usr/bin/dtach -N /tmp/iex_prompt"
+
+# Specify the user and group IDs for the Erlang VM
+#--uid 100
+#--gid 200
+
+# Uncomment to hang the board rather than rebooting when Erlang exits
+--hang-on-exit
+
+# Optionally run a program if the Erlang VM exits
+--run-on-exit /bin/sh
+
+# Enable UTF-8 filename handling in Erlang and custom inet configuration
+-e LANG=en_US.UTF-8;LANGUAGE=en;ERL_INETRC=/etc/erl_inetrc
+
+# Mount the application partition
+# See http://www.linuxfromscratch.org/lfs/view/6.3/chapter08/fstab.html about
+# ignoring warning the Linux kernel warning about using UTF8 with vfat.
+-m /dev/mmcblk0p3:/root:vfat::
+
+# Erlang release search path
+-r /srv/erlang
+
+# Assign a unique hostname based on the board id
+-d "/usr/bin/boardid -b rpi -n 4"
+-n nerves-%.4s
diff --git a/config/rootfs-additions-rpi3/etc/hostapd/hostapd.conf b/config/rootfs-additions-rpi3/etc/hostapd/hostapd.conf
new file mode 100644
index 00000000..7a2f10c1
--- /dev/null
+++ b/config/rootfs-additions-rpi3/etc/hostapd/hostapd.conf
@@ -0,0 +1,6 @@
+interface=wlan0
+ssid=FarmbotConfigurator
+hw_mode=g
+channel=6
+auth_algs=1
+wmm_enabled=0
diff --git a/config/rootfs-additions-rpi3/etc/hosts b/config/rootfs-additions-rpi3/etc/hosts
new file mode 100644
index 00000000..27ac24cd
--- /dev/null
+++ b/config/rootfs-additions-rpi3/etc/hosts
@@ -0,0 +1,2 @@
+127.0.0.1 localhost
+192.168.29.154 mqtt
diff --git a/config/rootfs-additions-rpi3/www/angular.min.js b/config/rootfs-additions-rpi3/www/angular.min.js
new file mode 100644
index 00000000..bf50a288
--- /dev/null
+++ b/config/rootfs-additions-rpi3/www/angular.min.js
@@ -0,0 +1,318 @@
+/*
+ AngularJS v1.5.8
+ (c) 2010-2016 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(C){'use strict';function N(a){return function(){var b=arguments[0],d;d="["+(a?a+":":"")+b+"] http://errors.angularjs.org/1.5.8/"+(a?a+"/":"")+b;for(b=1;b").append(a).html();try{return a[0].nodeType===Ma?Q(d):d.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+Q(b)})}catch(c){return Q(d)}}function zc(a){try{return decodeURIComponent(a)}catch(b){}}function Ac(a){var b={};q((a||"").split("&"),function(a){var c,e,f;a&&(e=a=a.replace(/\+/g,"%20"),
+c=a.indexOf("="),-1!==c&&(e=a.substring(0,c),f=a.substring(c+1)),e=zc(e),w(e)&&(f=w(f)?zc(f):!0,ua.call(b,e)?L(b[e])?b[e].push(f):b[e]=[b[e],f]:b[e]=f))});return b}function Tb(a){var b=[];q(a,function(a,c){L(a)?q(a,function(a){b.push(ea(c,!0)+(!0===a?"":"="+ea(a,!0)))}):b.push(ea(c,!0)+(!0===a?"":"="+ea(a,!0)))});return b.length?b.join("&"):""}function qb(a){return ea(a,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function ea(a,b){return encodeURIComponent(a).replace(/%40/gi,
+"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,b?"%20":"+")}function ee(a,b){var d,c,e=Na.length;for(c=0;c/,">"));}b=b||[];b.unshift(["$provide",function(b){b.value("$rootElement",a)}]);d.debugInfoEnabled&&b.push(["$compileProvider",function(a){a.debugInfoEnabled(!0)}]);b.unshift("ng");c=cb(b,d.strictDi);c.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",
+d);c(b)(a)})}]);return c},e=/^NG_ENABLE_DEBUG_INFO!/,f=/^NG_DEFER_BOOTSTRAP!/;C&&e.test(C.name)&&(d.debugInfoEnabled=!0,C.name=C.name.replace(e,""));if(C&&!f.test(C.name))return c();C.name=C.name.replace(f,"");ca.resumeBootstrap=function(a){q(a,function(a){b.push(a)});return c()};z(ca.resumeDeferredBootstrap)&&ca.resumeDeferredBootstrap()}function ge(){C.name="NG_ENABLE_DEBUG_INFO!"+C.name;C.location.reload()}function he(a){a=ca.element(a).injector();if(!a)throw xa("test");return a.get("$$testability")}
+function Cc(a,b){b=b||"_";return a.replace(ie,function(a,c){return(c?b:"")+a.toLowerCase()})}function je(){var a;if(!Dc){var b=rb();(qa=y(b)?C.jQuery:b?C[b]:void 0)&&qa.fn.on?(F=qa,S(qa.fn,{scope:Oa.scope,isolateScope:Oa.isolateScope,controller:Oa.controller,injector:Oa.injector,inheritedData:Oa.inheritedData}),a=qa.cleanData,qa.cleanData=function(b){for(var c,e=0,f;null!=(f=b[e]);e++)(c=qa._data(f,"events"))&&c.$destroy&&qa(f).triggerHandler("$destroy");a(b)}):F=O;ca.element=F;Dc=!0}}function sb(a,
+b,d){if(!a)throw xa("areq",b||"?",d||"required");return a}function Pa(a,b,d){d&&L(a)&&(a=a[a.length-1]);sb(z(a),b,"not a function, got "+(a&&"object"===typeof a?a.constructor.name||"Object":typeof a));return a}function Qa(a,b){if("hasOwnProperty"===a)throw xa("badname",b);}function Ec(a,b,d){if(!b)return a;b=b.split(".");for(var c,e=a,f=b.length,g=0;g$2>")+c[2];for(c=c[0];c--;)d=d.lastChild;f=$a(f,d.childNodes);d=e.firstChild;
+d.textContent=""}else f.push(b.createTextNode(a));e.textContent="";e.innerHTML="";q(f,function(a){e.appendChild(a)});return e}function Pc(a,b){var d=a.parentNode;d&&d.replaceChild(b,a);b.appendChild(a)}function O(a){if(a instanceof O)return a;var b;G(a)&&(a=W(a),b=!0);if(!(this instanceof O)){if(b&&"<"!=a.charAt(0))throw Wb("nosel");return new O(a)}if(b){b=C.document;var d;a=(d=Of.exec(a))?[b.createElement(d[1])]:(d=Oc(a,b))?d.childNodes:[]}Qc(this,a)}function Xb(a){return a.cloneNode(!0)}function wb(a,
+b){b||eb(a);if(a.querySelectorAll)for(var d=a.querySelectorAll("*"),c=0,e=d.length;c=Ea?!1:"function"===typeof a&&/^(?:class\b|constructor\()/.test(Function.prototype.toString.call(a)+" ");return d?(c.unshift(null),new (Function.prototype.bind.apply(a,c))):a.apply(b,c)},instantiate:function(a,b,c){var d=
+L(a)?a[a.length-1]:a;a=e(a,b,c);a.unshift(null);return new (Function.prototype.bind.apply(d,a))},get:d,annotate:cb.$$annotate,has:function(b){return n.hasOwnProperty(b+"Provider")||a.hasOwnProperty(b)}}}b=!0===b;var k={},l=[],m=new Ra([],!0),n={$provide:{provider:d(c),factory:d(f),service:d(function(a,b){return f(a,["$injector",function(a){return a.instantiate(b)}])}),value:d(function(a,b){return f(a,ha(b),!1)}),constant:d(function(a,b){Qa(a,"constant");n[a]=b;u[a]=b}),decorator:function(a,b){var c=
+p.get(a+"Provider"),d=c.$get;c.$get=function(){var a=B.invoke(d,c);return B.invoke(b,null,{$delegate:a})}}}},p=n.$injector=h(n,function(a,b){ca.isString(b)&&l.push(b);throw Ha("unpr",l.join(" <- "));}),u={},R=h(u,function(a,b){var c=p.get(a+"Provider",b);return B.invoke(c.$get,c,void 0,a)}),B=R;n.$injectorProvider={$get:ha(R)};var r=g(a),B=R.get("$injector");B.strictDi=b;q(r,function(a){a&&B.invoke(a)});return B}function Xe(){var a=!0;this.disableAutoScrolling=function(){a=!1};this.$get=["$window",
+"$location","$rootScope",function(b,d,c){function e(a){var b=null;Array.prototype.some.call(a,function(a){if("a"===wa(a))return b=a,!0});return b}function f(a){if(a){a.scrollIntoView();var c;c=g.yOffset;z(c)?c=c():Qb(c)?(c=c[0],c="fixed"!==b.getComputedStyle(c).position?0:c.getBoundingClientRect().bottom):T(c)||(c=0);c&&(a=a.getBoundingClientRect().top,b.scrollBy(0,a-c))}else b.scrollTo(0,0)}function g(a){a=G(a)?a:d.hash();var b;a?(b=h.getElementById(a))?f(b):(b=e(h.getElementsByName(a)))?f(b):"top"===
+a&&f(null):f(null)}var h=b.document;a&&c.$watch(function(){return d.hash()},function(a,b){a===b&&""===a||Qf(function(){c.$evalAsync(g)})});return g}]}function gb(a,b){if(!a&&!b)return"";if(!a)return b;if(!b)return a;L(a)&&(a=a.join(" "));L(b)&&(b=b.join(" "));return a+" "+b}function Zf(a){G(a)&&(a=a.split(" "));var b=U();q(a,function(a){a.length&&(b[a]=!0)});return b}function Ia(a){return D(a)?a:{}}function $f(a,b,d,c){function e(a){try{a.apply(null,va.call(arguments,1))}finally{if(R--,0===R)for(;B.length;)try{B.pop()()}catch(b){d.error(b)}}}
+function f(){t=null;g();h()}function g(){r=K();r=y(r)?null:r;na(r,E)&&(r=E);E=r}function h(){if(v!==k.url()||J!==r)v=k.url(),J=r,q(M,function(a){a(k.url(),r)})}var k=this,l=a.location,m=a.history,n=a.setTimeout,p=a.clearTimeout,u={};k.isMock=!1;var R=0,B=[];k.$$completeOutstandingRequest=e;k.$$incOutstandingRequestCount=function(){R++};k.notifyWhenNoOutstandingRequests=function(a){0===R?a():B.push(a)};var r,J,v=l.href,fa=b.find("base"),t=null,K=c.history?function(){try{return m.state}catch(a){}}:
+A;g();J=r;k.url=function(b,d,e){y(e)&&(e=null);l!==a.location&&(l=a.location);m!==a.history&&(m=a.history);if(b){var f=J===e;if(v===b&&(!c.history||f))return k;var h=v&&Ja(v)===Ja(b);v=b;J=e;!c.history||h&&f?(h||(t=b),d?l.replace(b):h?(d=l,e=b.indexOf("#"),e=-1===e?"":b.substr(e),d.hash=e):l.href=b,l.href!==b&&(t=b)):(m[d?"replaceState":"pushState"](e,"",b),g(),J=r);t&&(t=b);return k}return t||l.href.replace(/%27/g,"'")};k.state=function(){return r};var M=[],H=!1,E=null;k.onUrlChange=function(b){if(!H){if(c.history)F(a).on("popstate",
+f);F(a).on("hashchange",f);H=!0}M.push(b);return b};k.$$applicationDestroyed=function(){F(a).off("hashchange popstate",f)};k.$$checkUrlChange=h;k.baseHref=function(){var a=fa.attr("href");return a?a.replace(/^(https?\:)?\/\/[^\/]*/,""):""};k.defer=function(a,b){var c;R++;c=n(function(){delete u[c];e(a)},b||0);u[c]=!0;return c};k.defer.cancel=function(a){return u[a]?(delete u[a],p(a),e(A),!0):!1}}function df(){this.$get=["$window","$log","$sniffer","$document",function(a,b,d,c){return new $f(a,c,b,
+d)}]}function ef(){this.$get=function(){function a(a,c){function e(a){a!=n&&(p?p==a&&(p=a.n):p=a,f(a.n,a.p),f(a,n),n=a,n.n=null)}function f(a,b){a!=b&&(a&&(a.p=b),b&&(b.n=a))}if(a in b)throw N("$cacheFactory")("iid",a);var g=0,h=S({},c,{id:a}),k=U(),l=c&&c.capacity||Number.MAX_VALUE,m=U(),n=null,p=null;return b[a]={put:function(a,b){if(!y(b)){if(ll&&this.remove(p.key);return b}},get:function(a){if(l";b=pa.firstChild.attributes;var d=b[0];b.removeNamedItem(d.name);d.value=c;a.attributes.setNamedItem(d)}function x(a,b){try{a.addClass(b)}catch(c){}}function aa(a,b,c,d,e){a instanceof F||(a=F(a));for(var f=/\S+/,g=0,h=a.length;g<
+h;g++){var k=a[g];k.nodeType===Ma&&k.nodeValue.match(f)&&Pc(k,a[g]=C.document.createElement("span"))}var l=s(a,b,a,c,d,e);aa.$$addScopeClass(a);var m=null;return function(b,c,d){sb(b,"scope");e&&e.needsNewScope&&(b=b.$parent.$new());d=d||{};var f=d.parentBoundTranscludeFn,g=d.transcludeControllers;d=d.futureParentElement;f&&f.$$boundTransclude&&(f=f.$$boundTransclude);m||(m=(d=d&&d[0])?"foreignobject"!==wa(d)&&ma.call(d).match(/SVG/)?"svg":"html":"html");d="html"!==m?F(da(m,F("