Commit a4b64339 authored by Nicola Bertazzo's avatar Nicola Bertazzo

Merge branch 'release/1.0'

parents 41270ba6 a4346c3b
Pipeline #30 passed with stage
in 3 minutes and 19 seconds
.git
.gitignore
.idea
src
docker-compose.yml
Jenkinsfile
pom.xml
*.md
tmp
host-m2-repo
.m2
.DS_Store
packer_cache
output-*
*.box
*.vmdk
*.ovf
*.ovf
*.zip
*gz
*.iso
*.rendered
.vagrant
.idea
*.iml
tmp
target
builds
host-m2-repo
.m2
# This file is a template, and might need editing before it works on your project.
# this file is a template, and might need editing before it works on your project.
---
# Build JAVA applications using Apache Maven (http://maven.apache.org)
# For docker image tags see https://hub.docker.com/_/maven/
......@@ -29,65 +29,33 @@ cache:
paths:
- /root/.m2/repository/
# This will only validate and compile stuff and run e.g. maven-enforcer-plugin.
# Because some enforcer rules might check dependency convergence and class duplications
# we use `test-compile` here instead of `validate`, so the correct classpath is picked up.
.validate: &validate
stage: build
script:
- 'mvn $MAVEN_CLI_OPTS test-compile'
# For merge requests do not `deploy` but only run `verify`.
# See https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
.verify: &verify
stage: test
script:
- 'mvn $MAVEN_CLI_OPTS verify site site:stage'
except:
- master
# Validate merge requests using JDK8
validate:jdk8:
<<: *validate
build:
script: "mvn clean compile"
image: maven:3.3.9-jdk-8
tags:
- docker
# Verify merge requests using JDK8
verify:jdk8:
<<: *verify
test:
script: "mvn test"
image: maven:3.3.9-jdk-8
tags:
- docker
# For `master` branch run `mvn deploy` automatically.
# Here you need to decide whether you want to use JDK7 or 8.
# To get this working you need to define a volume while configuring your gitlab-ci-multi-runner.
# Mount your `settings.xml` as `/root/.m2/settings.xml` which holds your secrets.
# See https://maven.apache.org/settings.html
deploy:jdk8:
# Use stage test here, so the pages job may later pickup the created site.
stage: test
script:
- 'mvn $MAVEN_CLI_OPTS deploy site site:stage'
only:
- master
# Archive up the built documentation site.
artifacts:
paths:
- target/staging
package:
script: "mvn package"
image: maven:3.3.9-jdk-8
tags:
- docker
int-test:
script: "mvn verify"
image: maven:3.3.9-jdk-8
tags:
- docker
pages:
image: busybox:latest
stage: deploy
docker-build:
script:
# Because Maven appends the artifactId automatically to the staging path if you did define a parent pom,
# you might need to use `mv target/staging/YOUR_ARTIFACT_ID public` instead.
- mv target/staging public
dependencies:
- deploy:jdk8
artifacts:
paths:
- public
only:
- master
- "mvn package"
image: maven:3.3.9-jdk-8
tags:
- docker
\ No newline at end of file
FROM openjdk:8-jre-alpine
MAINTAINER Damien DUPORTAL <dduportal@cloudbees.com>
COPY ./target/demoapp.jar /app/app.jar
COPY hello-world.yml /app/config.yml
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]
CMD ["server","/app/config.yml"]
# DropWizard Demo Application
Welcome to the DropWizard Demo Application !
The goal of this repository is to show a tiny application example
to illustrate build pipelines and tools
## How to build it ?
### Requirements
To be built, this application needs:
* JDK 8 (OpenJDK is fine) as SDK
* **Maven 3.3** as build tool
### Get the code
Clone the repository wherever Maven + JDK is
available
* [Maven 3.3](https://maven.apache.org/) installation on "metal" with your JDK
* [A Maven + JDK Docker image](https://hub.docker.com/_/maven/)
* A [Virtual Machine with Maven and JDK](https://atlas.hashicorp.com/antapos/boxes/ubuntu-trusty64-jdk8-maven)
### Build it
From the root of the repository:
* Whole building process is as simple as
```bash
mvn clean install
```
* Just compiling classes:
```bash
mvn clean compile
```
* Running unit tests (implies compiling):
```bash
mvn test
```
* Running Integration tests (implies compiling but NO unit tests):
```bash
mvn verify
```
* Generating the standalone application:
```bash
mvn package
```
* "Installing" application in the local Maven repository:
```bash
mvn install
```
## How to run it ?
### Bare-metal
The [awesome DropWizard framework](http://www.dropwizard.io/1.0.0/docs/) makes the generated application a standalone one.
You can run it with just a Java JRE 8 installed:
```bash
java -jar ./target/demoapp.jar server ./hello-world.yml
```
The application will then be available on http://localhost:8080/ if everything went smoothly
### Docker run
They are a lot of reasons that would make you **NOT**
wanting to launch application in Bare Metal:
* Developer Syndrom (portability concerns): "It works on my machine" (**your** JDK and Maven installation)
* Security concerns: "What is this application doing ?"
* Ease of run: If any application is already running on
the `8080` port of your machine, you'll be required
to dig into the codebase + documentation to change
listening ports.
This is why you can run the application with your
own baked Docker image.
* A `Dockerfile` is provided at the root of the repository
* First step is to "build" the Docker image:
```bash
docker build -t dw-demo-app:latest ./
```
* Then run it in background,
letting Docker selecting a port:
```bash
CID=$(docker run -d -P dw-demo-app:latest)
```
* Fetch the allocated port by asking docker:
- Note that a simple ```docker ps``` could be sufficient, but not very machine-readable
```bash
docker port ${CID} 8080
```
Example: 0.0.0.0:**37567**
* Browse to the application homepage, using the fetched port: http://{DOCKER SERVICE IP}:**37567**
- {DOCKER SERVICE IP} is the IP address of your Docker service:
* `localhost` on Docker4Mac or Docker4Windows
* The result of ```boot2docker ip``` using Docker toolbox
* Stop and clean the application:
```bash
docker stop ${CID} && docker rm -v ${CID}
```
template: Hello, %s!
defaultName: Stranger
server:
rootPath: /api/
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dduportal.jenkins</groupId>
<artifactId>demoapp</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>Demo DropWizard Application</name>
<properties>
<dropwizard.version>1.0.0</dropwizard.version>
</properties>
<dependencies>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-core</artifactId>
<version>${dropwizard.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-testing</artifactId>
<version>${dropwizard.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-assets</artifactId>
<version>${dropwizard.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.dduportal.jenkins.demoapp.HelloWorldApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludedGroups>com.dduportal.jenkins.demoapp.test.IntegrationTest</excludedGroups>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/*.java</include>
</includes>
<groups>com.dduportal.jenkins.demoapp.test.IntegrationTest</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package com.dduportal.jenkins.demoapp;
import com.dduportal.jenkins.demoapp.health.TemplateHealthCheck;
import com.dduportal.jenkins.demoapp.resources.HelloWorldResource;
import io.dropwizard.Application;
import io.dropwizard.assets.AssetsBundle;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
public class HelloWorldApplication extends Application<HelloWorldConfiguration> {
public static void main(String[] args) throws Exception {
new HelloWorldApplication().run(args);
}
@Override
public String getName() {
return "hello-world";
}
@Override
public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
// nothing to do yet
bootstrap.addBundle(new AssetsBundle("/assets", "/","index.html"));
}
@Override
public void run(HelloWorldConfiguration configuration,
Environment environment) {
final HelloWorldResource resource = new HelloWorldResource(
configuration.getTemplate(),
configuration.getDefaultName()
);
final TemplateHealthCheck healthCheck =
new TemplateHealthCheck(configuration.getTemplate());
environment.healthChecks().register("template", healthCheck);
environment.jersey().register(resource);
environment.jersey().setUrlPattern("/api/*");
}
}
package com.dduportal.jenkins.demoapp;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.dropwizard.Configuration;
import org.hibernate.validator.constraints.NotEmpty;
public class HelloWorldConfiguration extends Configuration {
@NotEmpty
private String template;
@NotEmpty
private String defaultName = "Stranger";
@JsonProperty
public String getTemplate() {
return template;
}
@JsonProperty
public void setTemplate(String template) {
this.template = template;
}
@JsonProperty
public String getDefaultName() {
return defaultName;
}
@JsonProperty
public void setDefaultName(String name) {
this.defaultName = name;
}
}
package com.dduportal.jenkins.demoapp.api;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.Length;
public class Saying {
private long id;
@Length(max = 3)
private String content;
public Saying() {
// Jackson deserialization
}
public Saying(long id, String content) {
this.id = id;
this.content = content;
}
@JsonProperty
public long getId() {
return id;
}
@JsonProperty
public String getContent() {
return content;
}
}
package com.dduportal.jenkins.demoapp.health;
import com.codahale.metrics.health.HealthCheck;
public class TemplateHealthCheck extends HealthCheck {
private final String template;
public TemplateHealthCheck(String template) {
this.template = template;
}
@Override
protected Result check() throws Exception {
final String saying = String.format(template, "TEST");
if (!saying.contains("TEST")) {
return Result.unhealthy("template doesn't include a name");
}
return Result.healthy();
}
}
package com.dduportal.jenkins.demoapp.resources;
import com.dduportal.jenkins.demoapp.api.Saying;
import com.google.common.base.Optional;
import com.codahale.metrics.annotation.Timed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.concurrent.atomic.AtomicLong;
@Path("/hello-world")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldResource {
private final String template;
private final String defaultName;
private final AtomicLong counter;
public HelloWorldResource(String template, String defaultName) {
this.template = template;
this.defaultName = defaultName;
this.counter = new AtomicLong();
}
@GET
@Timed
public Saying sayHello(@QueryParam("name") Optional<String> name) {
final String value = String.format(template, name.or(defaultName));
return new Saying(counter.incrementAndGet(), value);
}
}
/*
AngularJS v1.0.8
(c) 2010-2012 Google, Inc. http://angularjs.org
License: MIT
*/
(function(P,T,q){'use strict';function m(b,a,c){var d;if(b)if(H(b))for(d in b)d!="prototype"&&d!="length"&&d!="name"&&b.hasOwnProperty(d)&&a.call(c,b[d],d);else if(b.forEach&&b.forEach!==m)b.forEach(a,c);else if(!b||typeof b.length!=="number"?0:typeof b.hasOwnProperty!="function"&&typeof b.constructor!="function"||b instanceof L||aa&&b instanceof aa||ma.call(b)!=="[object Object]"||typeof b.callee==="function")for(d=0;d<b.length;d++)a.call(c,b[d],d);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],
d);return b}function nb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function hc(b,a,c){for(var d=nb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function ob(b){return function(a,c){b(c,a)}}function xa(){for(var b=Z.length,a;b;){b--;a=Z[b].charCodeAt(0);if(a==57)return Z[b]="A",Z.join("");if(a==90)Z[b]="0";else return Z[b]=String.fromCharCode(a+1),Z.join("")}Z.unshift("0");return Z.join("")}function pb(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function D(b){var a=
b.$$hashKey;m(arguments,function(a){a!==b&&m(a,function(a,c){b[c]=a})});pb(b,a);return b}function G(b){return parseInt(b,10)}function ya(b,a){return D(new (D(function(){},{prototype:b})),a)}function s(){}function na(b){return b}function I(b){return function(){return b}}function u(b){return typeof b=="undefined"}function v(b){return typeof b!="undefined"}function M(b){return b!=null&&typeof b=="object"}function B(b){return typeof b=="string"}function Ra(b){return typeof b=="number"}function oa(b){return ma.apply(b)==
"[object Date]"}function E(b){return ma.apply(b)=="[object Array]"}function H(b){return typeof b=="function"}function Sa(b){return ma.apply(b)=="[object RegExp]"}function pa(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function ic(b){return b&&(b.nodeName||b.bind&&b.find)}function Ta(b,a,c){var d=[];m(b,function(b,g,h){d.push(a.call(c,b,g,h))});return d}function za(b,a){if(b.indexOf)return b.indexOf(a);for(var c=0;c<b.length;c++)if(a===b[c])return c;return-1}function Ua(b,a){var c=
za(b,a);c>=0&&b.splice(c,1);return a}function U(b,a){if(pa(b)||b&&b.$evalAsync&&b.$watch)throw Error("Can't copy Window or Scope");if(a){if(b===a)throw Error("Can't copy equivalent objects or arrays");if(E(b))for(var c=a.length=0;c<b.length;c++)a.push(U(b[c]));else{c=a.$$hashKey;m(a,function(b,c){delete a[c]});for(var d in b)a[d]=U(b[d]);pb(a,c)}}else(a=b)&&(E(b)?a=U(b,[]):oa(b)?a=new Date(b.getTime()):Sa(b)?a=RegExp(b.source):M(b)&&(a=U(b,{})));return a}function jc(b,a){var a=a||{},c;for(c in b)b.hasOwnProperty(c)&&
c.substr(0,2)!=="$$"&&(a[c]=b[c]);return a}function ea(b,a){if(b===a)return!0;if(b===null||a===null)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&c=="object")if(E(b)){if(!E(a))return!1;if((c=b.length)==a.length){for(d=0;d<c;d++)if(!ea(b[d],a[d]))return!1;return!0}}else if(oa(b))return oa(a)&&b.getTime()==a.getTime();else if(Sa(b)&&Sa(a))return b.toString()==a.toString();else{if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||pa(b)||pa(a)||E(a))return!1;c={};for(d in b)if(!(d.charAt(0)===
"$"||H(b[d]))){if(!ea(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c[d]&&d.charAt(0)!=="$"&&a[d]!==q&&!H(a[d]))return!1;return!0}return!1}function Va(b,a){var c=arguments.length>2?ha.call(arguments,2):[];return H(a)&&!(a instanceof RegExp)?c.length?function(){return arguments.length?a.apply(b,c.concat(ha.call(arguments,0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}:a}function kc(b,a){var c=a;/^\$+/.test(b)?c=q:pa(a)?c="$WINDOW":a&&T===a?c="$DOCUMENT":a&&a.$evalAsync&&
a.$watch&&(c="$SCOPE");return c}function ba(b,a){return typeof b==="undefined"?q:JSON.stringify(b,kc,a?" ":null)}function qb(b){return B(b)?JSON.parse(b):b}function Wa(b){b&&b.length!==0?(b=y(""+b),b=!(b=="f"||b=="0"||b=="false"||b=="no"||b=="n"||b=="[]")):b=!1;return b}function qa(b){b=w(b).clone();try{b.html("")}catch(a){}var c=w("<div>").append(b).html();try{return b[0].nodeType===3?y(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+y(b)})}catch(d){return y(c)}}function rb(b){try{return decodeURIComponent(b)}catch(a){}}
function Xa(b){var a={},c,d;m((b||"").split("&"),function(b){b&&(c=b.split("="),d=rb(c[0]),v(d)&&(a[d]=v(c[1])?rb(c[1]):!0))});return a}function sb(b){var a=[];m(b,function(b,d){a.push(Ya(d,!0)+(b===!0?"":"="+Ya(b,!0)))});return a.length?a.join("&"):""}function Za(b){return Ya(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Ya(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}
function lc(b,a){function c(a){a&&d.push(a)}var d=[b],e,g,h=["ng:app","ng-app","x-ng-app","data-ng-app"],f=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;m(h,function(a){h[a]=!0;c(T.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(m(b.querySelectorAll("."+a),c),m(b.querySelectorAll("."+a+"\\:"),c),m(b.querySelectorAll("["+a+"]"),c))});m(d,function(a){if(!e){var b=f.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):m(a.attributes,function(b){if(!e&&h[b.name])e=a,g=b.value})}});
e&&a(e,g?[g]:[])}function tb(b,a){var c=function(){b=w(b);a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");var c=ub(a);c.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(P&&!d.test(P.name))return c();P.name=P.name.replace(d,"");$a.resumeBootstrap=function(b){m(b,function(b){a.push(b)});c()}}function ab(b,a){a=a||"_";return b.replace(mc,function(b,
d){return(d?a:"")+b.toLowerCase()})}function bb(b,a,c){if(!b)throw Error("Argument '"+(a||"?")+"' is "+(c||"required"));return b}function ra(b,a,c){c&&E(b)&&(b=b[b.length-1]);bb(H(b),a,"not a function, got "+(b&&typeof b=="object"?b.constructor.name||"Object":typeof b));return b}function cb(b,a,c){if(!a)return b;for(var a=a.split("."),d,e=b,g=a.length,h=0;h<g;h++)d=a[h],b&&(b=(e=b)[d]);return!c&&H(b)?Va(e,b):b}function nc(b){function a(a,b,e){return a[b]||(a[b]=e())}return a(a(b,"angular",Object),
"module",function(){var b={};return function(d,e,g){e&&b.hasOwnProperty(d)&&(b[d]=null);return a(b,d,function(){function a(c,d,e){return function(){b[e||"push"]([c,d,arguments]);return k}}if(!e)throw Error("No module: "+d);var b=[],c=[],j=a("$injector","invoke"),k={_invokeQueue:b,_runBlocks:c,requires:e,name:d,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),filter:a("$filterProvider",
"register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:j,run:function(a){c.push(a);return this}};g&&j(g);return k})}})}function vb(b){return b.replace(oc,function(a,b,d,e){return e?d.toUpperCase():d}).replace(pc,"Moz$1")}function db(b,a,c,d){function e(b){var f;var e=c&&b?[this.filter(b)]:[this],i=a,j,k,l,n,o,p;if(!d||b!=null)for(;e.length;){j=e.shift();k=0;for(l=j.length;k<l;k++){n=w(j[k]);i?n.triggerHandler("$destroy"):i=!i;o=0;for(f=(p=n.children()).length,
n=f;o<n;o++)e.push(aa(p[o]))}}return g.apply(this,arguments)}var g=aa.fn[b],g=g.$original||g;e.$original=g;aa.fn[b]=e}function L(b){if(b instanceof L)return b;if(!(this instanceof L)){if(B(b)&&b.charAt(0)!="<")throw Error("selectors not implemented");return new L(b)}if(B(b)){var a=T.createElement("div");a.innerHTML="<div>&#160;</div>"+b;a.removeChild(a.firstChild);eb(this,a.childNodes);this.remove()}else eb(this,b)}function fb(b){return b.cloneNode(!0)}function sa(b){wb(b);for(var a=0,b=b.childNodes||
[];a<b.length;a++)sa(b[a])}function xb(b,a,c){var d=$(b,"events");$(b,"handle")&&(u(a)?m(d,function(a,c){gb(b,c,a);delete d[c]}):u(c)?(gb(b,a,d[a]),delete d[a]):Ua(d[a]||[],c))}function wb(b){var a=b[Aa],c=Ba[a];c&&(c.handle&&(c.events.$destroy&&c.handle({},"$destroy"),xb(b)),delete Ba[a],b[Aa]=q)}function $(b,a,c){var d=b[Aa],d=Ba[d||-1];if(v(c))d||(b[Aa]=d=++qc,d=Ba[d]={}),d[a]=c;else return d&&d[a]}function yb(b,a,c){var d=$(b,"data"),e=v(c),g=!e&&v(a),h=g&&!M(a);!d&&!h&&$(b,"data",d={});if(e)d[a]=
c;else if(g)if(h)return d&&d[a];else D(d,a);else return d}function Ca(b,a){return(" "+b.className+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" ")>-1}function zb(b,a){a&&m(a.split(" "),function(a){b.className=S((" "+b.className+" ").replace(/[\n\t]/g," ").replace(" "+S(a)+" "," "))})}function Ab(b,a){a&&m(a.split(" "),function(a){if(!Ca(b,a))b.className=S(b.className+" "+S(a))})}function eb(b,a){if(a)for(var a=!a.nodeName&&v(a.length)&&!pa(a)?a:[a],c=0;c<a.length;c++)b.push(a[c])}function Bb(b,a){return Da(b,
"$"+(a||"ngController")+"Controller")}function Da(b,a,c){b=w(b);for(b[0].nodeType==9&&(b=b.find("html"));b.length;){if(c=b.data(a))return c;b=b.parent()}}function Cb(b,a){var c=Ea[a.toLowerCase()];return c&&Db[b.nodeName]&&c}function rc(b,a){var c=function(c,e){if(!c.preventDefault)c.preventDefault=function(){c.returnValue=!1};if(!c.stopPropagation)c.stopPropagation=function(){c.cancelBubble=!0};if(!c.target)c.target=c.srcElement||T;if(u(c.defaultPrevented)){var g=c.preventDefault;c.preventDefault=
function(){c.defaultPrevented=!0;g.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=function(){return c.defaultPrevented};m(a[e||c.type],function(a){a.call(b,c)});V<=8?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function fa(b){var a=typeof b,c;if(a=="object"&&b!==null)if(typeof(c=b.$$hashKey)=="function")c=b.$$hashKey();else{if(c===q)c=b.$$hashKey=xa()}else c=b;return a+
":"+c}function Fa(b){m(b,this.put,this)}function hb(){}function Eb(b){var a,c;if(typeof b=="function"){if(!(a=b.$inject))a=[],c=b.toString().replace(sc,""),c=c.match(tc),m(c[1].split(uc),function(b){b.replace(vc,function(b,c,d){a.push(d)})}),b.$inject=a}else E(b)?(c=b.length-1,ra(b[c],"fn"),a=b.slice(0,c)):ra(b,"fn",!0);return a}function ub(b){function a(a){return function(b,c){if(M(b))m(b,ob(a));else return a(b,c)}}function c(a,b){if(H(b)||E(b))b=l.instantiate(b);if(!b.$get)throw Error("Provider "+
a+" must define $get factory method.");return k[a+f]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[];m(a,function(a){if(!j.get(a))if(j.put(a,!0),B(a)){var c=ta(a);b=b.concat(e(c.requires)).concat(c._runBlocks);try{for(var d=c._invokeQueue,c=0,f=d.length;c<f;c++){var g=d[c],p=g[0]=="$injector"?l:l.get(g[0]);p[g[1]].apply(p,g[2])}}catch(h){throw h.message&&(h.message+=" from "+a),h;}}else if(H(a))try{b.push(l.invoke(a))}catch(i){throw i.message&&(i.message+=" from "+a),i;}else if(E(a))try{b.push(l.invoke(a))}catch(o){throw o.message&&
(o.message+=" from "+String(a[a.length-1])),o;}else ra(a,"module")});return b}function g(a,b){function c(d){if(typeof d!=="string")throw Error("Service name expected");if(a.hasOwnProperty(d)){if(a[d]===h)throw Error("Circular dependency: "+i.join(" <- "));return a[d]}else try{return i.unshift(d),a[d]=h,a[d]=b(d)}finally{i.shift()}}function d(a,b,e){var f=[],j=Eb(a),g,h,p;h=0;for(g=j.length;h<g;h++)p=j[h],f.push(e&&e.hasOwnProperty(p)?e[p]:c(p));a.$inject||(a=a[g]);switch(b?-1:f.length){case 0:return a();
case 1:return a(f[0]);case 2:return a(f[0],f[1]);case 3:return a(f[0],f[1],f[2]);case 4:return a(f[0],f[1],f[2],f[3]);case 5:return a(f[0],f[1],f[2],f[3],f[4]);case 6:return a(f[0],f[1],f[2],f[3],f[4],f[5]);case 7:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6]);case 8:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7]);case 9:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8]);case 10:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9]);default:return a.apply(b,f)}}return{invoke:d,instantiate:function(a,
b){var c=function(){},e;c.prototype=(E(a)?a[a.length-1]:a).prototype;c=new c;e=d(a,c,b);return M(e)?e:c},get:c,annotate:Eb}}var h={},f="Provider",i=[],j=new Fa,k={$provide:{provider:a(c),factory:a(d),service:a(function(a,b){return d(a,["$injector",function(a){return a.instantiate(b)}])}),value:a(function(a,b){return d(a,I(b))}),constant:a(function(a,b){k[a]=b;n[a]=b}),decorator:function(a,b){var c=l.get(a+f),d=c.$get;c.$get=function(){var a=o.invoke(d,c);return o.invoke(b,null,{$delegate:a})}}}},
l=g(k,function(){throw Error("Unknown provider: "+i.join(" <- "));}),n={},o=n.$injector=g(n,function(a){a=l.get(a+f);return o.invoke(a.$get,a)});m(e(b),function(a){o.invoke(a||s)});return o}function wc(){var b=!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=null;m(a,function(a){!b&&y(a.nodeName)==="a"&&(b=a)});return b}function g(){var b=c.hash(),d;b?(d=h.getElementById(b))?d.scrollIntoView():(d=e(h.getElementsByName(b)))?
d.scrollIntoView():b==="top"&&a.scrollTo(0,0):a.scrollTo(0,0)}var h=a.document;b&&d.$watch(function(){return c.hash()},function(){d.$evalAsync(g)});return g}]}function xc(b,a,c,d){function e(a){try{a.apply(null,ha.call(arguments,1))}finally{if(p--,p===0)for(;z.length;)try{z.pop()()}catch(b){c.error(b)}}}function g(a,b){(function yc(){m(r,function(a){a()});x=b(yc,a)})()}function h(){N!=f.url()&&(N=f.url(),m(K,function(a){a(f.url())}))}var f=this,i=a[0],j=b.location,k=b.history,l=b.setTimeout,n=b.clearTimeout,
o={};f.isMock=!1;var p=0,z=[];f.$$completeOutstandingRequest=e;f.$$incOutstandingRequestCount=function(){p++};f.notifyWhenNoOutstandingRequests=function(a){m(r,function(a){a()});p===0?a():z.push(a)};var r=[],x;f.addPollFn=function(a){u(x)&&g(100,l);r.push(a);return a};var N=j.href,A=a.find("base"),J=null;f.url=function(a,b){if(a){if(N!=a)return N=a,d.history?b?k.replaceState(null,"",a):(k.pushState(null,"",a),A.attr("href",A.attr("href"))):b?(j.replace(a),J=a):(j.href=a,J=null),f}else return J||j.href.replace(/%27/g,
"'")};var K=[],C=!1;f.onUrlChange=function(a){C||(d.history&&w(b).bind("popstate",h),d.hashchange?w(b).bind("hashchange",h):f.addPollFn(h),C=!0);K.push(a);return a};f.baseHref=function(){var a=A.attr("href");return a?a.replace(/^https?\:\/\/[^\/]*/,""):""};var ga={},Q="",t=f.baseHref();f.cookies=function(a,b){var d,e,f,j;if(a)if(b===q)i.cookie=escape(a)+"=;path="+t+";expires=Thu, 01 Jan 1970 00:00:00 GMT";else{if(B(b))d=(i.cookie=escape(a)+"="+escape(b)+";path="+t).length+1,d>4096&&c.warn("Cookie '"+
a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!")}else{if(i.cookie!==Q){Q=i.cookie;d=Q.split("; ");ga={};for(f=0;f<d.length;f++)e=d[f],j=e.indexOf("="),j>0&&(a=unescape(e.substring(0,j)),ga[a]===q&&(ga[a]=unescape(e.substring(j+1))))}return ga}};f.defer=function(a,b){var c;p++;c=l(function(){delete o[c];e(a)},b||0);o[c]=!0;return c};f.defer.cancel=function(a){return o[a]?(delete o[a],n(a),e(s),!0):!1}}function zc(){this.$get=["$window","$log","$sniffer","$document",
function(b,a,c,d){return new xc(b,d,a,c)}]}function Ac(){this.$get=function(){function b(b,d){function e(a){if(a!=l){if(n){if(n==a)n=a.n}else n=a;g(a.n,a.p);g(a,l);l=a;l.n=null}}function g(a,b){if(a!=b){if(a)a.p=b;if(b)b.n=a}}if(b in a)throw Error("cacheId "+b+" taken");var h=0,f=D({},d,{id:b}),i={},j=d&&d.capacity||Number.MAX_VALUE,k={},l=null,n=null;return a[b]={put:function(a,b){var c=k[a]||(k[a]={key:a});e(c);u(b)||(a in i||h++,i[a]=b,h>j&&this.remove(n.key))},get:function(a){var b=k[a];if(b)return e(b),
i[a]},remove:function(a){var b=k[a];if(b){if(b==l)l=b.p;if(b==n)n=b.n;g(b.n,b.p);delete k[a];delete i[a];h--}},removeAll:function(){i={};h=0;k={};l=n=null},destroy:function(){k=f=i=null;delete a[b]},info:function(){return D({},f,{size:h})}}}var a={};b.info=function(){var b={};m(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function Bc(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function Fb(b){var a={},c="Directive",d=/^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
e=/(([\d\w\-_]+)(?:\:([^;]+))?;?)/,g="Template must have exactly one root element. was: ",h=/^\s*(https?|ftp|mailto|file):/;this.directive=function i(d,e){B(d)?(bb(e,"directive"),a.hasOwnProperty(d)||(a[d]=[],b.factory(d+c,["$injector","$exceptionHandler",function(b,c){var e=[];m(a[d],function(a){try{var g=b.invoke(a);if(H(g))g={compile:I(g)};else if(!g.compile&&g.link)g.compile=I(g.link);g.priority=g.priority||0;g.name=g.name||d;g.require=g.require||g.controller&&g.name;g.restrict=g.restrict||"A";
e.push(g)}catch(h){c(h)}});return e}])),a[d].push(e)):m(d,ob(i));return this};this.urlSanitizationWhitelist=function(a){return v(a)?(h=a,this):h};this.$get=["$injector","$interpolate","$exceptionHandler","$http","$templateCache","$parse","$controller","$rootScope","$document",function(b,j,k,l,n,o,p,z,r){function x(a,b,c){a instanceof w||(a=w(a));m(a,function(b,c){b.nodeType==3&&b.nodeValue.match(/\S+/)&&(a[c]=w(b).wrap("<span></span>").parent()[0])});var d=A(a,b,a,c);return function(b,c){bb(b,"scope");
for(var e=c?va.clone.call(a):a,g=0,j=e.length;g<j;g++){var h=e[g];(h.nodeType==1||h.nodeType==9)&&e.eq(g).data("$scope",b)}N(e,"ng-scope");c&&c(e,b);d&&d(b,e,e);return e}}function N(a,b){try{a.addClass(b)}catch(c){}}function A(a,b,c,d){function e(a,c,d,j){var h,i,k,p,o,l,n,r=[];o=0;for(l=c.length;o<l;o++)r.push(c[o]);n=o=0;for(l=g.length;o<l;n++)i=r[n],c=g[o++],h=g[o++],c?(c.scope?(k=a.$new(M(c.scope)),w(i).data("$scope",k)):k=a,(p=c.transclude)||!j&&b?c(h,k,i,d,function(b){return function(c){var d=
a.$new();d.$$transcluded=!0;return b(d,c).bind("$destroy",Va(d,d.$destroy))}}(p||b)):c(h,k,i,q,j)):h&&h(a,i.childNodes,q,j)}for(var g=[],j,h,i,k=0;k<a.length;k++)h=new ia,j=J(a[k],[],h,d),h=(j=j.length?K(j,a[k],h,b,c):null)&&j.terminal||!a[k].childNodes||!a[k].childNodes.length?null:A(a[k].childNodes,j?j.transclude:b),g.push(j),g.push(h),i=i||j||h;return i?e:null}function J(a,b,c,g){var j=c.$attr,h;switch(a.nodeType){case 1:C(b,ca(Ga(a).toLowerCase()),"E",g);var i,k,o;h=a.attributes;for(var p=0,l=
h&&h.length;p<l;p++)if(i=h[p],!V||V>=8||i.specified)k=i.name,o=ca(k.toLowerCase()),j[o]=k,c[o]=i=S(V&&k=="href"?decodeURIComponent(a.getAttribute(k,2)):i.value),Cb(a,o)&&(c[o]=!0),R(a,b,i,o),C(b,o,"A",g);a=a.className;if(B(a)&&a!=="")for(;h=e.exec(a);)o=ca(h[2]),C(b,o,"C",g)&&(c[o]=S(h[3])),a=a.substr(h.index+h[0].length);break;case 3:Y(b,a.nodeValue);break;case 8:try{if(h=d.exec(a.nodeValue))o=ca(h[1]),C(b,o,"M",g)&&(c[o]=S(h[2]))}catch(n){}}b.sort(t);return b}function K(a,b,c,d,e){function j(a,
b){if(a)a.require=t.require,n.push(a);if(b)b.require=t.require,r.push(b)}function h(a,b){var c,d="data",e=!1;if(B(a)){for(;(c=a.charAt(0))=="^"||c=="?";)a=a.substr(1),c=="^"&&(d="inheritedData"),e=e||c=="?";c=b[d]("$"+a+"Controller");if(!c&&!e)throw Error("No controller: "+a);}else E(a)&&(c=[],m(a,function(a){c.push(h(a,b))}));return c}function i(a,d,e,g,j){var l,z,t,F,N;l=b===e?c:jc(c,new ia(w(e),c.$attr));z=l.$$element;if(K){var Cc=/^\s*([@=&])\s*(\w*)\s*$/,x=d.$parent||d;m(K.scope,function(a,b){var c=
a.match(Cc)||[],e=c[2]||b,c=c[1],g,j,h;d.$$isolateBindings[b]=c+e;switch(c){case "@":l.$observe(e,function(a){d[b]=a});l.$$observers[e].$$scope=x;break;case "=":j=o(l[e]);h=j.assign||function(){g=d[b]=j(x);throw Error(Gb+l[e]+" (directive: "+K.name+")");};g=d[b]=j(x);d.$watch(function(){var a=j(x);a!==d[b]&&(a!==g?g=d[b]=a:h(x,a=g=d[b]));return a});break;case "&":j=o(l[e]);d[b]=function(a){return j(x,a)};break;default:throw Error("Invalid isolate scope definition for directive "+K.name+": "+a);}})}Y&&
m(Y,function(a){var b={$scope:d,$element:z,$attrs:l,$transclude:j};N=a.controller;N=="@"&&(N=l[a.name]);z.data("$"+a.name+"Controller",p(N,b))});g=0;for(t=n.length;g<t;g++)try{F=n[g],F(d,z,l,F.require&&h(F.require,z))}catch(A){k(A,qa(z))}a&&a(d,e.childNodes,q,j);g=0;for(t=r.length;g<t;g++)try{F=r[g],F(d,z,l,F.require&&h(F.require,z))}catch(Dc){k(Dc,qa(z))}}for(var l=-Number.MAX_VALUE,n=[],r=[],z=null,K=null,A=null,F=c.$$element=w(b),t,C,R,ja,da=d,Y,s,u,D=0,y=a.length;D<y;D++){t=a[D];R=