From 4ea10b410f3598f60ffcb7472b26322a597317b4 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 11:09:46 +0800 Subject: [PATCH 01/31] remove unused files --- src/main/java/overview.html | 7 ------- src/main/java/test.html | 39 ------------------------------------- 2 files changed, 46 deletions(-) delete mode 100644 src/main/java/overview.html delete mode 100644 src/main/java/test.html diff --git a/src/main/java/overview.html b/src/main/java/overview.html deleted file mode 100644 index df4f4d6b7..000000000 --- a/src/main/java/overview.html +++ /dev/null @@ -1,7 +0,0 @@ - - -

- The Spring Data Binding framework, an internal library used by Spring Web Flow. -

- - \ No newline at end of file diff --git a/src/main/java/test.html b/src/main/java/test.html deleted file mode 100644 index 9a7a99675..000000000 --- a/src/main/java/test.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - -

Organisation

- -

Speakers

- - - - - - - - - -
- Sergiu Bodiu -

Sergiu Bodiu

-

Java Consultant at Bank of America

- Seasoned consultant experienced in large-scale e-commerce projects, passionate about providing innovative technology solutions to solve complex business problems, have extensive knowledge and experience delivering enterprise wide applications. He is skilled in software design, data modeling, stakeholder management, IT strategic planning, technical know-how and security. Able to design, implement, test and maintain software product components with strong focus on design elegance and software reuse. -
- Sergiu Bodiu -

Sergiu Bodiu

-

Java Consultant at Bank of America

- Seasoned consultant experienced in large-scale e-commerce projects, passionate about providing innovative technology solutions to solve complex business problems, have extensive knowledge and experience delivering enterprise wide applications. He is skilled in software design, data modeling, stakeholder management, IT strategic planning, technical know-how and security. Able to design, implement, test and maintain software product components with strong focus on design elegance and software reuse. -
From 080f9e4142c9de8af57e60bf0d3911fd0630dae2 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 11:10:33 +0800 Subject: [PATCH 02/31] remove unused files --- src/main/webapp/resources/npm-debug.log | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 src/main/webapp/resources/npm-debug.log diff --git a/src/main/webapp/resources/npm-debug.log b/src/main/webapp/resources/npm-debug.log deleted file mode 100644 index 0996c1a25..000000000 --- a/src/main/webapp/resources/npm-debug.log +++ /dev/null @@ -1,19 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ 'node', '/usr/local/bin/npm', 'install' ] -2 info using npm@2.7.4 -3 info using node@v0.12.2 -4 error install Couldn't read dependencies -5 verbose stack Error: ENOENT, open '/Users/isvym/work/workspaces/samples/petclinic-angular/src/main/webapp/resources/package.json' -5 verbose stack at Error (native) -6 verbose cwd /Users/isvym/work/workspaces/samples/petclinic-angular/src/main/webapp/resources -7 error Darwin 13.4.0 -8 error argv "node" "/usr/local/bin/npm" "install" -9 error node v0.12.2 -10 error npm v2.7.4 -11 error path /Users/isvym/work/workspaces/samples/petclinic-angular/src/main/webapp/resources/package.json -12 error code ENOPACKAGEJSON -13 error errno -2 -14 error package.json ENOENT, open '/Users/isvym/work/workspaces/samples/petclinic-angular/src/main/webapp/resources/package.json' -14 error package.json This is most likely not a problem with npm itself. -14 error package.json npm can't find a package.json file in your current directory. -15 verbose exit [ -2, true ] From 7c131fd4dc0f7f18fde0b1dc9ddc8155e59e2250 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 15:01:01 +0800 Subject: [PATCH 03/31] add simple error handler for OwnerController.js --- .../scripts/app/owner/OwnerController.js | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/main/webapp/scripts/app/owner/OwnerController.js b/src/main/webapp/scripts/app/owner/OwnerController.js index b03f7a2d1..fd02669f9 100644 --- a/src/main/webapp/scripts/app/owner/OwnerController.js +++ b/src/main/webapp/scripts/app/owner/OwnerController.js @@ -12,8 +12,8 @@ function loadOwner($scope, $resource, $stateParams) { */ angular.module('controllers').controller('ownerSearchController', ['$scope', '$state', function($scope, $state) { - - $scope.ownerSearchForm = {}; + + $scope.ownerSearchForm = {}; // form always needs to be initialised // otherwise we can't read $scope.ownerSearchForm.lastName @@ -27,13 +27,13 @@ angular.module('controllers').controller('ownerSearchController', ['$scope', '$s */ angular.module('controllers').controller('ownerListController', ['$scope', '$resource', '$stateParams', function($scope, $resource, $stateParams) { - + var destUrl = '/petclinic/owner/list?lastName='; if(angular.isDefined($stateParams.lastName)) { destUrl += $stateParams.lastName; } var ownerResource = $resource(destUrl); - $scope.ownerList = ownerResource.query(); + $scope.ownerList = ownerResource.query(); }]); /* @@ -50,33 +50,43 @@ angular.module('controllers').controller('ownerDetailController', ['$scope', '$r */ angular.module('controllers').controller('ownerFormController', ['$scope', '$http', '$resource', '$stateParams', '$state', function($scope, $http, $resource, $stateParams, $state) { - + $scope.submitOwnerForm = {}; - + $scope.submitOwnerForm = function() { var form = $scope.owner; - + // Creating a Javascript object var data = { firstName: form.firstName, lastName: form.lastName, address: form.address, city: form.city, - telephone: form.telephone + telephone: form.telephone }; - - if ($state.current.name == 'app.owneredit') { - var restUrl = "/petclinic/owner/" + $stateParams.id; - $http.put(restUrl, data); - $state.go('app.ownerlist'); - } - else { // in case of owner creation - var restUrl = "/petclinic/owner"; - $http.post(restUrl, data); - $state.go('app.ownerlist'); - } + + var request; + + if ($state.current.name == 'app.owneredit') { + var restUrl = "/petclinic/owner/" + $stateParams.id; + request = $http.put(restUrl, data); + } + else { // in case of owner creation + var restUrl = "/petclinic/owner"; + request = $http.post(restUrl, data); + } + + request.then(function () { + $state.go('app.ownerlist'); + }, function (response) { + var error = response.data; + alert(error.error + "\r\n" + error.errors.map(function (e) { + return e.field + ": " + e.defaultMessage; + }).join("\r\n")); + }); + } - + if ($state.current.name == 'app.owneredit') { loadOwner($scope, $resource, $stateParams); } From f22bfed274d31d1fd02678399066c83540d38cb7 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 15:01:58 +0800 Subject: [PATCH 04/31] format codes --- src/main/webapp/scripts/app/owner/OwnerController.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/webapp/scripts/app/owner/OwnerController.js b/src/main/webapp/scripts/app/owner/OwnerController.js index fd02669f9..75284f07f 100644 --- a/src/main/webapp/scripts/app/owner/OwnerController.js +++ b/src/main/webapp/scripts/app/owner/OwnerController.js @@ -70,8 +70,7 @@ function($scope, $http, $resource, $stateParams, $state) { if ($state.current.name == 'app.owneredit') { var restUrl = "/petclinic/owner/" + $stateParams.id; request = $http.put(restUrl, data); - } - else { // in case of owner creation + } else { // in case of owner creation var restUrl = "/petclinic/owner"; request = $http.post(restUrl, data); } From 175cf7dfacea4df25d603befd443b1a5848a6638 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 15:03:02 +0800 Subject: [PATCH 05/31] migrate to spring-data for repositories --- .../petclinic/repository/OwnerRepository.java | 51 ++---- .../petclinic/repository/PetRepository.java | 30 ++-- .../petclinic/repository/VetRepository.java | 3 +- .../petclinic/repository/VisitRepository.java | 3 +- .../jdbc/JdbcOwnerRepositoryImpl.java | 167 ------------------ .../petclinic/repository/jdbc/JdbcPet.java | 49 ----- .../jdbc/JdbcPetRepositoryImpl.java | 133 -------------- .../repository/jdbc/JdbcPetRowMapper.java | 42 ----- .../jdbc/JdbcVetRepositoryImpl.java | 92 ---------- .../jdbc/JdbcVisitRepositoryImpl.java | 110 ------------ .../repository/jdbc/package-info.java | 9 - .../jpa/JpaOwnerRepositoryImpl.java | 82 --------- .../repository/jpa/JpaPetRepositoryImpl.java | 64 ------- .../repository/jpa/JpaVetRepositoryImpl.java | 51 ------ .../jpa/JpaVisitRepositoryImpl.java | 65 ------- .../repository/jpa/package-info.java | 9 - .../SpringDataOwnerRepository.java | 41 ----- .../SpringDataPetRepository.java | 38 ---- .../SpringDataVetRepository.java | 29 --- .../SpringDataVisitRepository.java | 29 --- 20 files changed, 35 insertions(+), 1062 deletions(-) delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java diff --git a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java index 131833706..841d0bcd8 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java @@ -1,18 +1,3 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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. - */ /* * Copyright 2002-2013 the original author or authors. * @@ -33,6 +18,9 @@ package org.springframework.samples.petclinic.repository; import java.util.Collection; import org.springframework.dao.DataAccessException; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.query.Param; import org.springframework.samples.petclinic.model.BaseEntity; import org.springframework.samples.petclinic.model.Owner; @@ -45,36 +33,31 @@ import org.springframework.samples.petclinic.model.Owner; * @author Sam Brannen * @author Michael Isvy */ -public interface OwnerRepository { +public interface OwnerRepository extends Repository { /** - * Retrieve Owners from the data store by last name, returning all owners whose last name starts - * with the given name. - * + * Retrieve {@link Owner}s from the data store by last name, returning all owners + * whose last name starts with the given name. * @param lastName Value to search for - * @return a Collection of matching Owners (or an empty Collection if none - * found) + * @return a Collection of matching {@link Owner}s (or an empty Collection if none + * found) */ - Collection findByLastName(String lastName) throws DataAccessException; + @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") + Collection findByLastName(@Param("lastName") String lastName); /** - * Retrieve an Owner from the data store by id. - * + * Retrieve an {@link Owner} from the data store by id. * @param id the id to search for - * @return the Owner if found - * @throws org.springframework.dao.DataRetrievalFailureException - * if not found + * @return the {@link Owner} if found */ - Owner findById(int id) throws DataAccessException; - + @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") + Owner findById(@Param("id") int id); /** - * Save an Owner to the data store, either inserting or updating it. - * - * @param owner the Owner to save - * @see BaseEntity#isNew + * Save an {@link Owner} to the data store, either inserting or updating it. + * @param owner the {@link Owner} to save */ - void save(Owner owner) throws DataAccessException; + void save(Owner owner); } diff --git a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java index 693b2e5e9..58e73d7f6 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java @@ -18,6 +18,8 @@ package org.springframework.samples.petclinic.repository; import java.util.List; import org.springframework.dao.DataAccessException; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.BaseEntity; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; @@ -31,31 +33,27 @@ import org.springframework.samples.petclinic.model.PetType; * @author Sam Brannen * @author Michael Isvy */ -public interface PetRepository { +public interface PetRepository extends Repository { /** - * Retrieve all PetTypes from the data store. - * - * @return a Collection of PetTypes + * Retrieve all {@link PetType}s from the data store. + * @return a Collection of {@link PetType}s. */ - List findPetTypes() throws DataAccessException; + @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name") + List findPetTypes(); /** - * Retrieve a Pet from the data store by id. - * + * Retrieve a {@link Pet} from the data store by id. * @param id the id to search for - * @return the Pet if found - * @throws org.springframework.dao.DataRetrievalFailureException - * if not found + * @return the {@link Pet} if found */ - Pet findById(int id) throws DataAccessException; + Pet findById(int id); /** - * Save a Pet to the data store, either inserting or updating it. - * - * @param pet the Pet to save - * @see BaseEntity#isNew + * Save a {@link Pet} to the data store, either inserting or updating it. + * @param pet the {@link Pet} to save */ - void save(Pet pet) throws DataAccessException; + void save(Pet pet); } + diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java index 923c3c23d..aabdfd65d 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java @@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.repository; import java.util.Collection; import org.springframework.dao.DataAccessException; +import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.Vet; /** @@ -29,7 +30,7 @@ import org.springframework.samples.petclinic.model.Vet; * @author Sam Brannen * @author Michael Isvy */ -public interface VetRepository { +public interface VetRepository extends Repository { /** * Retrieve all Vets from the data store. diff --git a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java index 96b7a208c..e734f3275 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java @@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.repository; import java.util.List; import org.springframework.dao.DataAccessException; +import org.springframework.data.repository.Repository; import org.springframework.samples.petclinic.model.BaseEntity; import org.springframework.samples.petclinic.model.Visit; @@ -30,7 +31,7 @@ import org.springframework.samples.petclinic.model.Visit; * @author Sam Brannen * @author Michael Isvy */ -public interface VisitRepository { +public interface VisitRepository extends Repository { /** * Save a Visit to the data store, either inserting or updating it. diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java deleted file mode 100644 index 579de5284..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcOwnerRepositoryImpl.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jdbc; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.BeanPropertyRowMapper; -import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.core.simple.SimpleJdbcInsert; -import org.springframework.orm.ObjectRetrievalFailureException; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.repository.OwnerRepository; -import org.springframework.samples.petclinic.repository.VisitRepository; -import org.springframework.samples.petclinic.util.EntityUtils; -import org.springframework.stereotype.Repository; - -/** - * A simple JDBC-based implementation of the {@link OwnerRepository} interface. - * - * @author Ken Krebs - * @author Juergen Hoeller - * @author Rob Harrop - * @author Sam Brannen - * @author Thomas Risberg - * @author Mark Fisher - */ -@Repository -public class JdbcOwnerRepositoryImpl implements OwnerRepository { - - private VisitRepository visitRepository; - - private NamedParameterJdbcTemplate namedParameterJdbcTemplate; - - private SimpleJdbcInsert insertOwner; - - @Autowired - public JdbcOwnerRepositoryImpl(DataSource dataSource, NamedParameterJdbcTemplate namedParameterJdbcTemplate, - VisitRepository visitRepository) { - - this.insertOwner = new SimpleJdbcInsert(dataSource) - .withTableName("owners") - .usingGeneratedKeyColumns("id"); - - this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); - - this.visitRepository = visitRepository; - } - - - /** - * Loads {@link Owner Owners} from the data store by last name, returning all owners whose last name starts with - * the given name; also loads the {@link Pet Pets} and {@link Visit Visits} for the corresponding owners, if not - * already loaded. - */ - @Override - public Collection findByLastName(String lastName) throws DataAccessException { - Map params = new HashMap(); - params.put("lastName", lastName + "%"); - List owners = this.namedParameterJdbcTemplate.query( - "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like :lastName", - params, - BeanPropertyRowMapper.newInstance(Owner.class) - ); - loadOwnersPetsAndVisits(owners); - return owners; - } - - /** - * Loads the {@link Owner} with the supplied id; also loads the {@link Pet Pets} and {@link Visit Visits} - * for the corresponding owner, if not already loaded. - */ - @Override - public Owner findById(int id) throws DataAccessException { - Owner owner; - try { - Map params = new HashMap(); - params.put("id", id); - owner = this.namedParameterJdbcTemplate.queryForObject( - "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id= :id", - params, - BeanPropertyRowMapper.newInstance(Owner.class) - ); - } catch (EmptyResultDataAccessException ex) { - throw new ObjectRetrievalFailureException(Owner.class, id); - } - loadPetsAndVisits(owner); - return owner; - } - - public void loadPetsAndVisits(final Owner owner) { - Map params = new HashMap(); - params.put("id", owner.getId().intValue()); - final List pets = this.namedParameterJdbcTemplate.query( - "SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE owner_id=:id", - params, - new JdbcPetRowMapper() - ); - for (JdbcPet pet : pets) { - owner.addPet(pet); - // Pet types have not been loaded at this stage. They are loaded separately - pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId())); - List visits = this.visitRepository.findByPetId(pet.getId()); - for (Visit visit : visits) { - pet.addVisit(visit); - } - } - } - - @Override - public void save(Owner owner) throws DataAccessException { - BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(owner); - if (owner.isNew()) { - Number newKey = this.insertOwner.executeAndReturnKey(parameterSource); - owner.setId(newKey.intValue()); - } else { - this.namedParameterJdbcTemplate.update( - "UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " + - "city=:city, telephone=:telephone WHERE id=:id", - parameterSource); - } - } - - public Collection getPetTypes() throws DataAccessException { - return this.namedParameterJdbcTemplate.query( - "SELECT id, name FROM types ORDER BY name", new HashMap(), - BeanPropertyRowMapper.newInstance(PetType.class)); - } - - /** - * Loads the {@link Pet} and {@link Visit} data for the supplied {@link List} of {@link Owner Owners}. - * - * @param owners the list of owners for whom the pet and visit data should be loaded - * @see #loadPetsAndVisits(Owner) - */ - private void loadOwnersPetsAndVisits(List owners) { - for (Owner owner : owners) { - loadPetsAndVisits(owner); - } - } - - -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java deleted file mode 100644 index 39ba53b83..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPet.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jdbc; - -import org.springframework.samples.petclinic.model.Pet; - -/** - * Subclass of Pet that carries temporary id properties which are only relevant for a JDBC implementation of the - * PetRepository. - * - * @author Juergen Hoeller - */ -class JdbcPet extends Pet { - - private int typeId; - - private int ownerId; - - - public void setTypeId(int typeId) { - this.typeId = typeId; - } - - public int getTypeId() { - return this.typeId; - } - - public void setOwnerId(int ownerId) { - this.ownerId = ownerId; - } - - public int getOwnerId() { - return this.ownerId; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java deleted file mode 100644 index 546451dcc..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRepositoryImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jdbc; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.BeanPropertyRowMapper; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.jdbc.core.simple.SimpleJdbcInsert; -import org.springframework.orm.ObjectRetrievalFailureException; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.repository.OwnerRepository; -import org.springframework.samples.petclinic.repository.PetRepository; -import org.springframework.samples.petclinic.repository.VisitRepository; -import org.springframework.samples.petclinic.util.EntityUtils; -import org.springframework.stereotype.Repository; - -/** - * @author Ken Krebs - * @author Juergen Hoeller - * @author Rob Harrop - * @author Sam Brannen - * @author Thomas Risberg - * @author Mark Fisher - */ -@Repository -public class JdbcPetRepositoryImpl implements PetRepository { - - private NamedParameterJdbcTemplate namedParameterJdbcTemplate; - - private SimpleJdbcInsert insertPet; - - private OwnerRepository ownerRepository; - - private VisitRepository visitRepository; - - - @Autowired - public JdbcPetRepositoryImpl(DataSource dataSource, OwnerRepository ownerRepository, VisitRepository visitRepository) { - this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); - - this.insertPet = new SimpleJdbcInsert(dataSource) - .withTableName("pets") - .usingGeneratedKeyColumns("id"); - - this.ownerRepository = ownerRepository; - this.visitRepository = visitRepository; - } - - @Override - public List findPetTypes() throws DataAccessException { - Map params = new HashMap(); - return this.namedParameterJdbcTemplate.query( - "SELECT id, name FROM types ORDER BY name", - params, - BeanPropertyRowMapper.newInstance(PetType.class)); - } - - @Override - public Pet findById(int id) throws DataAccessException { - JdbcPet pet; - try { - Map params = new HashMap(); - params.put("id", id); - pet = this.namedParameterJdbcTemplate.queryForObject( - "SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=:id", - params, - new JdbcPetRowMapper()); - } catch (EmptyResultDataAccessException ex) { - throw new ObjectRetrievalFailureException(Pet.class, new Integer(id)); - } - Owner owner = this.ownerRepository.findById(pet.getOwnerId()); - owner.addPet(pet); - pet.setType(EntityUtils.getById(findPetTypes(), PetType.class, pet.getTypeId())); - - List visits = this.visitRepository.findByPetId(pet.getId()); - for (Visit visit : visits) { - pet.addVisit(visit); - } - return pet; - } - - @Override - public void save(Pet pet) throws DataAccessException { - if (pet.isNew()) { - Number newKey = this.insertPet.executeAndReturnKey( - createPetParameterSource(pet)); - pet.setId(newKey.intValue()); - } else { - this.namedParameterJdbcTemplate.update( - "UPDATE pets SET name=:name, birth_date=:birth_date, type_id=:type_id, " + - "owner_id=:owner_id WHERE id=:id", - createPetParameterSource(pet)); - } - } - - /** - * Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Pet} instance. - */ - private MapSqlParameterSource createPetParameterSource(Pet pet) { - return new MapSqlParameterSource() - .addValue("id", pet.getId()) - .addValue("name", pet.getName()) - .addValue("birth_date", pet.getBirthDate().toDate()) - .addValue("type_id", pet.getType().getId()) - .addValue("owner_id", pet.getOwner().getId()); - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java deleted file mode 100644 index 4164f746f..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcPetRowMapper.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jdbc; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Date; - -import org.joda.time.DateTime; -import org.springframework.jdbc.core.BeanPropertyRowMapper; - -/** - * {@link BeanPropertyRowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties - * of the {@link JdbcPet} class. - */ -class JdbcPetRowMapper extends BeanPropertyRowMapper { - - @Override - public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException { - JdbcPet pet = new JdbcPet(); - pet.setId(rs.getInt("id")); - pet.setName(rs.getString("name")); - Date birthDate = rs.getDate("birth_date"); - pet.setBirthDate(new DateTime(birthDate)); - pet.setTypeId(rs.getInt("type_id")); - pet.setOwnerId(rs.getInt("owner_id")); - return pet; - } -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java deleted file mode 100644 index 9a85bde11..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVetRepositoryImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jdbc; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.BeanPropertyRowMapper; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.samples.petclinic.model.Specialty; -import org.springframework.samples.petclinic.model.Vet; -import org.springframework.samples.petclinic.repository.VetRepository; -import org.springframework.samples.petclinic.util.EntityUtils; -import org.springframework.stereotype.Repository; - -/** - * A simple JDBC-based implementation of the {@link VetRepository} interface. Uses @Cacheable to cache the result of the - * {@link findAll} method - * - * @author Ken Krebs - * @author Juergen Hoeller - * @author Rob Harrop - * @author Sam Brannen - * @author Thomas Risberg - * @author Mark Fisher - * @author Michael Isvy - */ -@Repository -public class JdbcVetRepositoryImpl implements VetRepository { - - private JdbcTemplate jdbcTemplate; - - @Autowired - public JdbcVetRepositoryImpl(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - /** - * Refresh the cache of Vets that the ClinicService is holding. - * - * @see org.springframework.samples.petclinic.model.service.ClinicService#shouldFindVets() - */ - @Override - public Collection findAll() throws DataAccessException { - List vets = new ArrayList(); - // Retrieve the list of all vets. - vets.addAll(this.jdbcTemplate.query( - "SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name", - BeanPropertyRowMapper.newInstance(Vet.class))); - - // Retrieve the list of all possible specialties. - final List specialties = this.jdbcTemplate.query( - "SELECT id, name FROM specialties", - BeanPropertyRowMapper.newInstance(Specialty.class)); - - // Build each vet's list of specialties. - for (Vet vet : vets) { - final List vetSpecialtiesIds = this.jdbcTemplate.query( - "SELECT specialty_id FROM vet_specialties WHERE vet_id=?", - new BeanPropertyRowMapper() { - @Override - public Integer mapRow(ResultSet rs, int row) throws SQLException { - return Integer.valueOf(rs.getInt(1)); - } - }, - vet.getId().intValue()); - for (int specialtyId : vetSpecialtiesIds) { - Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId); - vet.addSpecialty(specialty); - } - } - return vets; - } -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java deleted file mode 100644 index b6a004561..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/JdbcVisitRepositoryImpl.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jdbc; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Date; -import java.util.List; - -import javax.sql.DataSource; - -import org.joda.time.DateTime; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.BeanPropertyRowMapper; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.simple.SimpleJdbcInsert; -import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.repository.VisitRepository; -import org.springframework.stereotype.Repository; - -/** - * A simple JDBC-based implementation of the {@link VisitRepository} interface. - * - * @author Ken Krebs - * @author Juergen Hoeller - * @author Rob Harrop - * @author Sam Brannen - * @author Thomas Risberg - * @author Mark Fisher - * @author Michael Isvy - */ -@Repository -public class JdbcVisitRepositoryImpl implements VisitRepository { - - private JdbcTemplate jdbcTemplate; - - private SimpleJdbcInsert insertVisit; - - @Autowired - public JdbcVisitRepositoryImpl(DataSource dataSource) { - this.jdbcTemplate = new JdbcTemplate(dataSource); - - this.insertVisit = new SimpleJdbcInsert(dataSource) - .withTableName("visits") - .usingGeneratedKeyColumns("id"); - } - - - @Override - public void save(Visit visit) throws DataAccessException { - if (visit.isNew()) { - Number newKey = this.insertVisit.executeAndReturnKey( - createVisitParameterSource(visit)); - visit.setId(newKey.intValue()); - } else { - throw new UnsupportedOperationException("Visit update not supported"); - } - } - - public void deletePet(int id) throws DataAccessException { - this.jdbcTemplate.update("DELETE FROM pets WHERE id=?", id); - } - - - /** - * Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Visit} instance. - */ - private MapSqlParameterSource createVisitParameterSource(Visit visit) { - return new MapSqlParameterSource() - .addValue("id", visit.getId()) - .addValue("visit_date", visit.getDate().toDate()) - .addValue("description", visit.getDescription()) - .addValue("pet_id", visit.getPet().getId()); - } - - @Override - public List findByPetId(Integer petId) { - final List visits = this.jdbcTemplate.query( - "SELECT id, visit_date, description FROM visits WHERE pet_id=?", - new BeanPropertyRowMapper() { - @Override - public Visit mapRow(ResultSet rs, int row) throws SQLException { - Visit visit = new Visit(); - visit.setId(rs.getInt("id")); - Date visitDate = rs.getDate("visit_date"); - visit.setDate(new DateTime(visitDate)); - visit.setDescription(rs.getString("description")); - return visit; - } - }, - petId); - return visits; - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java b/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java deleted file mode 100644 index edd0bf855..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jdbc/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ - -/** - * - * The classes in this package represent the JDBC implementation - * of PetClinic's persistence layer. - * - */ -package org.springframework.samples.petclinic.repository.jdbc; - diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java deleted file mode 100644 index c7398df5b..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaOwnerRepositoryImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jpa; - -import java.util.Collection; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -import org.springframework.orm.hibernate3.support.OpenSessionInViewFilter; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.repository.OwnerRepository; -import org.springframework.stereotype.Repository; - -/** - * JPA implementation of the {@link OwnerRepository} interface. - * - * @author Mike Keith - * @author Rod Johnson - * @author Sam Brannen - * @author Michael Isvy - * @since 22.4.2006 - */ -@Repository -public class JpaOwnerRepositoryImpl implements OwnerRepository { - - @PersistenceContext - private EntityManager em; - - - /** - * Important: in the current version of this method, we load Owners with all their Pets and Visits while - * we do not need Visits at all and we only need one property from the Pet objects (the 'name' property). - * There are some ways to improve it such as: - * - creating a Ligtweight class (example here: https://community.jboss.org/wiki/LightweightClass) - * - Turning on lazy-loading and using {@link OpenSessionInViewFilter} - */ - @SuppressWarnings("unchecked") - public Collection findByLastName(String lastName) { - // using 'join fetch' because a single query should load both owners and pets - // using 'left join fetch' because it might happen that an owner does not have pets yet - Query query = this.em.createQuery("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName"); - query.setParameter("lastName", lastName + "%"); - return query.getResultList(); - } - - @Override - public Owner findById(int id) { - // using 'join fetch' because a single query should load both owners and pets - // using 'left join fetch' because it might happen that an owner does not have pets yet - Query query = this.em.createQuery("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id"); - query.setParameter("id", id); - return (Owner) query.getSingleResult(); - } - - - @Override - public void save(Owner owner) { - if (owner.getId() == null) { - this.em.persist(owner); - } - else { - this.em.merge(owner); - } - - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java deleted file mode 100644 index 84d564da4..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaPetRepositoryImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jpa; - -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.repository.PetRepository; -import org.springframework.stereotype.Repository; - -/** - * JPA implementation of the {@link PetRepository} interface. - * - * @author Mike Keith - * @author Rod Johnson - * @author Sam Brannen - * @author Michael Isvy - * @since 22.4.2006 - */ -@Repository -public class JpaPetRepositoryImpl implements PetRepository { - - @PersistenceContext - private EntityManager em; - - @Override - @SuppressWarnings("unchecked") - public List findPetTypes() { - return this.em.createQuery("SELECT ptype FROM PetType ptype ORDER BY ptype.name").getResultList(); - } - - @Override - public Pet findById(int id) { - return this.em.find(Pet.class, id); - } - - @Override - public void save(Pet pet) { - if (pet.getId() == null) { - this.em.persist(pet); - } - else { - this.em.merge(pet); - } - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java deleted file mode 100644 index e4c222b65..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVetRepositoryImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jpa; - -import java.util.Collection; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - -import org.springframework.cache.annotation.Cacheable; -import org.springframework.samples.petclinic.model.Vet; -import org.springframework.samples.petclinic.repository.VetRepository; -import org.springframework.stereotype.Repository; - -/** - * JPA implementation of the {@link VetRepository} interface. - * - * @author Mike Keith - * @author Rod Johnson - * @author Sam Brannen - * @author Michael Isvy - * @since 22.4.2006 - */ -@Repository -public class JpaVetRepositoryImpl implements VetRepository { - - @PersistenceContext - private EntityManager em; - - - @Override - @Cacheable(value = "vets") - @SuppressWarnings("unchecked") - public Collection findAll() { - return this.em.createQuery("SELECT distinct vet FROM Vet vet left join fetch vet.specialties ORDER BY vet.lastName, vet.firstName").getResultList(); - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java deleted file mode 100644 index 3415def96..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/JpaVisitRepositoryImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.jpa; - -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.repository.VisitRepository; -import org.springframework.stereotype.Repository; - -/** - * JPA implementation of the ClinicService interface using EntityManager. - *

- *

The mappings are defined in "orm.xml" located in the META-INF directory. - * - * @author Mike Keith - * @author Rod Johnson - * @author Sam Brannen - * @author Michael Isvy - * @since 22.4.2006 - */ -@Repository -public class JpaVisitRepositoryImpl implements VisitRepository { - - @PersistenceContext - private EntityManager em; - - - @Override - public void save(Visit visit) { - if (visit.getId() == null) { - this.em.persist(visit); - } - else { - this.em.merge(visit); - } - } - - - @Override - @SuppressWarnings("unchecked") - public List findByPetId(Integer petId) { - Query query = this.em.createQuery("SELECT visit FROM Visit v where v.pets.id= :id"); - query.setParameter("id", petId); - return query.getResultList(); - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java b/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java deleted file mode 100644 index 13c8552ed..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/jpa/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ - -/** - * - * The classes in this package represent the JPA implementation - * of PetClinic's persistence layer. - * - */ -package org.springframework.samples.petclinic.repository.jpa; - diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java deleted file mode 100644 index ca1f709f6..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataOwnerRepository.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.springdatajpa; - -import java.util.Collection; - -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.data.repository.query.Param; -import org.springframework.samples.petclinic.model.Owner; -import org.springframework.samples.petclinic.repository.OwnerRepository; - -/** - * Spring Data JPA specialization of the {@link OwnerRepository} interface - * - * @author Michael Isvy - * @since 15.1.2013 - */ -public interface SpringDataOwnerRepository extends OwnerRepository, Repository { - - @Override - @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") - public Collection findByLastName(@Param("lastName") String lastName); - - @Override - @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") - public Owner findById(@Param("id") int id); -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java deleted file mode 100644 index 56a413147..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataPetRepository.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.springdatajpa; - -import java.util.List; - -import org.springframework.dao.DataAccessException; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.samples.petclinic.model.Pet; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.repository.PetRepository; - -/** - * Spring Data JPA specialization of the {@link PetRepository} interface - * - * @author Michael Isvy - * @since 15.1.2013 - */ -public interface SpringDataPetRepository extends PetRepository, Repository { - - @Override - @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name") - List findPetTypes() throws DataAccessException; -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java deleted file mode 100644 index b8211b707..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVetRepository.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.springdatajpa; - -import org.springframework.data.repository.Repository; -import org.springframework.samples.petclinic.model.Vet; -import org.springframework.samples.petclinic.repository.VetRepository; - -/** - * Spring Data JPA specialization of the {@link VetRepository} interface - * - * @author Michael Isvy - * @since 15.1.2013 - */ -public interface SpringDataVetRepository extends VetRepository, Repository { -} diff --git a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java deleted file mode 100644 index 84740224b..000000000 --- a/src/main/java/org/springframework/samples/petclinic/repository/springdatajpa/SpringDataVisitRepository.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.repository.springdatajpa; - -import org.springframework.data.repository.Repository; -import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.repository.VisitRepository; - -/** - * Spring Data JPA specialization of the {@link VisitRepository} interface - * - * @author Michael Isvy - * @since 15.1.2013 - */ -public interface SpringDataVisitRepository extends VisitRepository, Repository { -} From 8c4e2749141c9fa8baa0f02bf75915c37909172a Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 15:03:53 +0800 Subject: [PATCH 06/31] remove dependency with joda time to simplify the project dependencies --- .../samples/petclinic/model/Pet.java | 31 +++++++++---------- .../samples/petclinic/model/Visit.java | 24 +++++++------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/model/Pet.java b/src/main/java/org/springframework/samples/petclinic/model/Pet.java index d618f08bb..a121e7b81 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Pet.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Pet.java @@ -15,11 +15,9 @@ */ package org.springframework.samples.petclinic.model; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.springframework.beans.support.MutableSortDefinition; +import org.springframework.beans.support.PropertyComparator; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -29,13 +27,14 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; - -import org.hibernate.annotations.Type; -import org.joda.time.DateTime; -import org.springframework.beans.support.MutableSortDefinition; -import org.springframework.beans.support.PropertyComparator; - -import com.fasterxml.jackson.annotation.JsonIgnore; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * Simple business object representing a pet. @@ -49,8 +48,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; public class Pet extends NamedEntity { @Column(name = "birth_date") - @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") - private DateTime birthDate; + @Temporal(TemporalType.DATE) + private Date birthDate; @ManyToOne @JoinColumn(name = "type_id") @@ -65,11 +64,11 @@ public class Pet extends NamedEntity { private Set visits; - public void setBirthDate(DateTime birthDate) { + public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } - public DateTime getBirthDate() { + public Date getBirthDate() { return this.birthDate; } diff --git a/src/main/java/org/springframework/samples/petclinic/model/Visit.java b/src/main/java/org/springframework/samples/petclinic/model/Visit.java index 181830abc..a418c17a7 100644 --- a/src/main/java/org/springframework/samples/petclinic/model/Visit.java +++ b/src/main/java/org/springframework/samples/petclinic/model/Visit.java @@ -15,18 +15,18 @@ */ package org.springframework.samples.petclinic.model; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.format.annotation.DateTimeFormat; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; - -import org.hibernate.annotations.Type; -import org.hibernate.validator.constraints.NotEmpty; -import org.joda.time.DateTime; -import org.springframework.format.annotation.DateTimeFormat; - -import com.fasterxml.jackson.annotation.JsonIgnore; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.util.Date; /** * Simple JavaBean domain object representing a visit. @@ -41,9 +41,9 @@ public class Visit extends BaseEntity { * Holds value of property date. */ @Column(name = "visit_date") - @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") + @Temporal(TemporalType.TIMESTAMP) @DateTimeFormat(pattern = "yyyy/MM/dd") - private DateTime date; + private Date date; /** * Holds value of property description. @@ -65,7 +65,7 @@ public class Visit extends BaseEntity { * Creates a new instance of Visit for the current date */ public Visit() { - this.date = new DateTime(); + this.date = new Date(); } @@ -74,7 +74,7 @@ public class Visit extends BaseEntity { * * @return Value of property date. */ - public DateTime getDate() { + public Date getDate() { return this.date; } @@ -83,7 +83,7 @@ public class Visit extends BaseEntity { * * @param date New value of property date. */ - public void setDate(DateTime date) { + public void setDate(Date date) { this.date = date; } From a2a9725618659c9b17374e84f132eca3b8c59879 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 15:04:07 +0800 Subject: [PATCH 07/31] format codes --- .../samples/petclinic/util/CallMonitoringAspect.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java b/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java index 3c699842f..2ddcf5f6c 100644 --- a/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java +++ b/src/main/java/org/springframework/samples/petclinic/util/CallMonitoringAspect.java @@ -66,10 +66,11 @@ public class CallMonitoringAspect { @ManagedAttribute public long getCallTime() { - if (this.callCount > 0) - return this.accumulatedCallTime / this.callCount; - else - return 0; + if (this.callCount > 0) { + return this.accumulatedCallTime / this.callCount; + } else { + return 0; + } } From db3fc815be1b7da89ff69c0b181d37a8a37a507b Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 16:48:58 +0800 Subject: [PATCH 08/31] restructure ui layout --- pom.xml | 452 ++---------------- .../petclinic/PetClinicApplication.java | 12 + .../petclinic/web/CrashController.java | 40 -- .../samples/petclinic/web/OwnerResource.java | 4 +- .../samples/petclinic/web/PetResource.java | 47 +- .../petclinic/web/PetTypeFormatter.java | 66 --- .../samples/petclinic/web/PetValidator.java | 6 +- .../samples/petclinic/web/VetResource.java | 7 +- .../petclinic/web/VisitController.java | 8 +- .../samples/petclinic/web/package-info.java | 8 - src/main/resources/application.properties | 22 + src/main/resources/cache/ehcache.xml | 17 - src/main/resources/cache/ehcache.xsd | 419 ---------------- .../datatables/datatables.properties | 6 - src/main/resources/logback.xml | 25 - src/main/resources/spring/business-config.xml | 96 ---- .../resources/spring/data-access.properties | 41 -- .../resources/spring/datasource-config.xml | 43 -- src/main/resources/spring/mvc-core-config.xml | 75 --- src/main/resources/spring/mvc-view-config.xml | 15 - src/main/resources/spring/tools-config.xml | 49 -- src/main/webapp/WEB-INF/web.xml | 95 ---- src/main/webapp/index.html | 7 +- src/main/webapp/resources/css/petclinic.css | 20 - .../scripts/app/fragments/bodyHeader.html | 41 +- .../webapp/scripts/app/fragments/footer.html | 13 +- .../webapp/scripts/app/pet/PetController.js | 6 +- src/main/webapp/scripts/app/pet/petForm.html | 60 ++- 28 files changed, 182 insertions(+), 1518 deletions(-) create mode 100644 src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/web/CrashController.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java delete mode 100644 src/main/java/org/springframework/samples/petclinic/web/package-info.java create mode 100644 src/main/resources/application.properties delete mode 100644 src/main/resources/cache/ehcache.xml delete mode 100644 src/main/resources/cache/ehcache.xsd delete mode 100644 src/main/resources/dandelion/datatables/datatables.properties delete mode 100644 src/main/resources/logback.xml delete mode 100644 src/main/resources/spring/business-config.xml delete mode 100644 src/main/resources/spring/data-access.properties delete mode 100644 src/main/resources/spring/datasource-config.xml delete mode 100644 src/main/resources/spring/mvc-core-config.xml delete mode 100644 src/main/resources/spring/mvc-view-config.xml delete mode 100644 src/main/resources/spring/tools-config.xml delete mode 100644 src/main/webapp/WEB-INF/web.xml diff --git a/pom.xml b/pom.xml index fefabaeec..adb519718 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,13 @@ 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + org.springframework.samples spring-petclinic 1.0.0-SNAPSHOT @@ -8,441 +15,72 @@ petclinic war - - - - 1.8 - UTF-8 - UTF-8 - - - 4.1.6.RELEASE - 1.8.0.RELEASE - - - - 2.2 - 1.2 - 7.0.47 - 2.2.7 - - - 4.3.8.Final - - - 4.3.1.Final - - - 7.0.42 - 2.6.10 - 2.3.2 - - - 1.8.5 - - - 1.1.3 - 1.7.12 - - - 2.0.0 - - - 4.12 - 3.0.0 - - - 1.3 - 1.1.1 - 2.7 - 3.2.0.GA - 2.4.5 - - - - 2.3.0 - 1.10.3 - 2.0.3-1 - 0.10.1 - - 5.1.22 - - 2.7 - - - - org.jadira.usertype - usertype.core - ${jadira-usertype-core.version} + org.springframework.boot + spring-boot-starter-web - - org.apache.tomcat - tomcat-servlet-api - ${tomcat.servlet.version} - provided - - - javax.servlet.jsp - jsp-api - 2.1 - provided - - - org.glassfish.web - jstl-impl - 1.2 - - - javax.servlet - servlet-api - - - - com.sun.xml.bind - jaxb-impl - ${jaxb-impl.version} + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-cache + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-devtools + + + + org.apache.tomcat.embed + tomcat-embed-jasper provided - - - com.jayway.jsonpath - json-path - ${json-path.version} - test - - - - org.springframework.data - spring-data-jpa - ${spring-data-jpa.version} - - - org.springframework - * - - - - - org.springframework - spring-jdbc - ${spring-framework.version} - - - org.springframework - spring-aop - ${spring-framework.version} - - - org.springframework - spring-webmvc - ${spring-framework.version} - - - org.springframework - spring-tx - ${spring-framework.version} - - - - org.springframework - spring-context-support - ${spring-framework.version} - - - org.springframework - spring-orm - ${spring-framework.version} - - - org.springframework - spring-oxm - ${spring-framework.version} - - - commons-lang - commons-lang - - + javax.servlet + jstl - - org.aspectj - aspectjrt - ${aspectj.version} - - - org.aspectj - aspectjweaver - ${aspectj.version} - runtime - - - - - org.apache.tomcat - tomcat-jdbc - ${tomcat-jdbc.version} - runtime - - - - - org.slf4j - slf4j-api - ${slf4j.version} - compile - - - ch.qos.logback - logback-classic - ${logback.version} - runtime - - - - - joda-time - joda-time - ${jodatime.version} - - - com.fasterxml.jackson.datatype - jackson-datatype-joda - ${jackson.datatype.joda.version} - - - - joda-time - joda-time-hibernate - ${jodatime-hibernate.version} - - - joda-time - joda-time-jsptags - ${jodatime-jsptags.version} - - - - org.hsqldb hsqldb - ${hsqldb.version} runtime - - - - - org.hibernate - hibernate-entitymanager - ${hibernate.version} - - - org.hibernate - hibernate-validator - ${hibernate-validator.version} - - - - org.hibernate - hibernate-ehcache - ${hibernate.version} - - - net.sf.ehcache - ehcache-core - ${ehcache.version} - - - commons-logging - commons-logging - - - - - - org.webjars - bootstrap - ${webjars-bootstrap.version} - - - org.webjars - jquery-ui - ${webjars-jquery-ui.version} - - - org.webjars - jquery - ${webjars-jquery.version} - - - - - org.springframework - spring-test - ${spring-framework.version} - test - - - junit - junit - ${junit.version} - test - - - org.assertj - assertj-core - ${assertj.version} - + + org.projectlombok + lombok + 1.16.10 + provided + - - com.github.dandelion - datatables-jsp - ${dandelion.version} - - - com.github.dandelion - datatables-export-itext - ${dandelion.version} + org.springframework.boot + spring-boot-starter-test + test - - install - - - - ${project.basedir}/src/test/java - - - ${project.basedir}/src/test/resources - - - org.apache.maven.plugins - maven-compiler-plugin - 3.0 + org.springframework.boot + spring-boot-maven-plugin - - - - true - ${java.version} - ${java.version} - true + true - - org.apache.maven.plugins - maven-surefire-plugin - 2.13 - - - **/*Tests.java - - - - - org.apache.maven.plugins - maven-war-plugin - 2.3 - - petclinic - - - - org.apache.maven.plugins - maven-eclipse-plugin - 2.9 - - true - true - 2.0 - - **/*.* - - - - org.springframework.ide.eclipse.core.springbuilder - - - org.eclipse.m2e.core.maven2Builder - - - - org.eclipse.jdt.core.javanature - org.springframework.ide.eclipse.core.springnature - org.eclipse.m2e.core.maven2Nature - - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.4 - - - jar-with-dependencies - - - - - org.apache.tomcat.maven - tomcat7-maven-plugin - 2.2 - - tomcat-development-server - 9966 - /petclinic - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.version} - - - - - - clean - check - - - - - - - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura.version} - - - html - - - - - - - demopetclinic diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java new file mode 100644 index 000000000..72dc6087a --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -0,0 +1,12 @@ +package org.springframework.samples.petclinic; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PetClinicApplication { + + public static void main(String[] args) { + SpringApplication.run(PetClinicApplication.class, args); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/web/CrashController.java b/src/main/java/org/springframework/samples/petclinic/web/CrashController.java deleted file mode 100644 index e413f3f3b..000000000 --- a/src/main/java/org/springframework/samples/petclinic/web/CrashController.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.web; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * Controller used to showcase what happens when an exception is thrown - * - * @author Michael Isvy - *

- * Also see how the bean of type 'SimpleMappingExceptionResolver' has been declared inside - * /WEB-INF/mvc-core-config.xml - */ -@Controller -public class CrashController { - - @RequestMapping(value = "/oups", method = RequestMethod.GET) - public String triggerException() { - throw new RuntimeException("Expected: controller used to showcase what " + - "happens when an exception is thrown"); - } - - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java index 851a3ff75..e9cba805c 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java +++ b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java @@ -31,6 +31,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import javax.validation.Valid; + /** * @author Juergen Hoeller * @author Ken Krebs @@ -98,7 +100,7 @@ public class OwnerResource { * Update Owner */ @RequestMapping(value = "/owner/{ownerId}", method = RequestMethod.PUT) - public Owner updateOwner(@PathVariable("ownerId") int ownerId, @RequestBody Owner ownerRequest) { + public Owner updateOwner(@PathVariable("ownerId") int ownerId, @Valid @RequestBody Owner ownerRequest) { Owner ownerModel = retrieveOwner(ownerId); // This is done by hand for simplicity purpose. In a real life use-case we should consider using MapStruct. ownerModel.setFirstName(ownerRequest.getFirstName()); diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetResource.java b/src/main/java/org/springframework/samples/petclinic/web/PetResource.java index 3651968bb..c96b3571b 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/PetResource.java +++ b/src/main/java/org/springframework/samples/petclinic/web/PetResource.java @@ -15,19 +15,23 @@ */ package org.springframework.samples.petclinic.web; -import java.util.Collection; +import java.util.Date; import java.util.Map; +import lombok.Getter; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @@ -43,23 +47,22 @@ public class PetResource { private final ClinicService clinicService; - @Autowired public PetResource(ClinicService clinicService) { this.clinicService = clinicService; } - @ModelAttribute("types") - public Collection populatePetTypes() { - return this.clinicService.findPetTypes(); - } - @InitBinder public void setAllowedFields(WebDataBinder dataBinder) { dataBinder.setDisallowedFields("id"); } - @RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.GET) + @GetMapping("/petTypes") + Object getPetTypes() { + return clinicService.findPetTypes(); + } + + @GetMapping("/owners/{ownerId}/pets/new") public String initCreationForm(@PathVariable("ownerId") int ownerId, Map model) { Owner owner = this.clinicService.findOwnerById(ownerId); Pet pet = new Pet(); @@ -68,7 +71,7 @@ public class PetResource { return "pets/createOrUpdatePetForm"; } - @RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.POST) + @PostMapping("/owners/{ownerId}/pets/new") public String processCreationForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) { new PetValidator().validate(pet, result); if (result.hasErrors()) { @@ -80,10 +83,10 @@ public class PetResource { } } - @RequestMapping(value = "/owner/*/pet/{petId}", method = RequestMethod.GET) - public Pet findPet(@PathVariable("petId") int petId) { + @GetMapping("/owner/*/pet/{petId}") + public PetDetails findPet(@PathVariable("petId") int petId) { Pet pet = this.clinicService.findPetById(petId); - return pet; + return new PetDetails(pet); } @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/edit", method = {RequestMethod.PUT, RequestMethod.POST}) @@ -99,4 +102,24 @@ public class PetResource { } } + @Getter + static class PetDetails { + + long id; + String name; + String owner; + @DateTimeFormat(pattern = "yyyy-MM-dd") + Date birthDate; + PetType type; + + PetDetails(Pet pet) { + this.id = pet.getId(); + this.name = pet.getName(); + this.owner = pet.getOwner().getFirstName() + " " + pet.getOwner().getLastName(); + this.birthDate = pet.getBirthDate(); + this.type = pet.getType(); + } + + } + } diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java deleted file mode 100644 index 3d47d2201..000000000 --- a/src/main/java/org/springframework/samples/petclinic/web/PetTypeFormatter.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.web; - - -import java.text.ParseException; -import java.util.Collection; -import java.util.Locale; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.format.Formatter; -import org.springframework.samples.petclinic.model.PetType; -import org.springframework.samples.petclinic.service.ClinicService; - -/** - * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have - * come as an improvement in comparison to legacy PropertyEditors. See the following links for more details: - The - * Spring ref doc: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html#format-Formatter-SPI - * - A nice blog entry from Gordon Dickens: http://gordondickens.com/wordpress/2010/09/30/using-spring-3-0-custom-type-converter/ - *

- * Also see how the bean 'conversionService' has been declared inside /WEB-INF/mvc-core-config.xml - * - * @author Mark Fisher - * @author Juergen Hoeller - * @author Michael Isvy - */ -public class PetTypeFormatter implements Formatter { - - private final ClinicService clinicService; - - - @Autowired - public PetTypeFormatter(ClinicService clinicService) { - this.clinicService = clinicService; - } - - @Override - public String print(PetType petType, Locale locale) { - return petType.getName(); - } - - @Override - public PetType parse(String text, Locale locale) throws ParseException { - Collection findPetTypes = this.clinicService.findPetTypes(); - for (PetType type : findPetTypes) { - if (type.getName().equals(text)) { - return type; - } - } - throw new ParseException("type not found: " + text, 0); - } - -} diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java index 03a1bca7c..fbb7dd5be 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java +++ b/src/main/java/org/springframework/samples/petclinic/web/PetValidator.java @@ -35,14 +35,14 @@ public class PetValidator { } else if (pet.isNew() && pet.getOwner().getPet(name, true) != null) { errors.rejectValue("name", "duplicate", "already exists"); } - + // type validation if (pet.isNew() && pet.getType() == null) { errors.rejectValue("type", "required", "required"); } - + // birth date validation - if (pet.getBirthDate()==null) { + if (pet.getBirthDate() == null) { errors.rejectValue("birthDate", "required", "required"); } } diff --git a/src/main/java/org/springframework/samples/petclinic/web/VetResource.java b/src/main/java/org/springframework/samples/petclinic/web/VetResource.java index 968c4d259..7661e97f4 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/VetResource.java +++ b/src/main/java/org/springframework/samples/petclinic/web/VetResource.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.samples.petclinic.model.Vet; import org.springframework.samples.petclinic.service.ClinicService; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @@ -36,17 +37,13 @@ public class VetResource { private final ClinicService clinicService; - @Autowired public VetResource(ClinicService clinicService) { this.clinicService = clinicService; } - @RequestMapping(value="/vets", method = RequestMethod.GET, - produces = MediaType.APPLICATION_JSON_VALUE) + @GetMapping("/vets") public Collection showResourcesVetList() { return this.clinicService.findVets(); } - - } diff --git a/src/main/java/org/springframework/samples/petclinic/web/VisitController.java b/src/main/java/org/springframework/samples/petclinic/web/VisitController.java index f3f6f3ffb..705ed2b5c 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/VisitController.java +++ b/src/main/java/org/springframework/samples/petclinic/web/VisitController.java @@ -26,9 +26,11 @@ import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -72,13 +74,13 @@ public class VisitController { } // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called - @RequestMapping(value = "/owners/*/pets/{petId}/visits/new", method = RequestMethod.GET) + @GetMapping("/owners/*/pets/{petId}/visits/new") public String initNewVisitForm(@PathVariable("petId") int petId, Map model) { return "pets/createOrUpdateVisitForm"; } // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called - @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/visits/new", method = RequestMethod.POST) + @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new") public String processNewVisitForm(@Valid Visit visit, BindingResult result) { if (result.hasErrors()) { return "pets/createOrUpdateVisitForm"; @@ -88,7 +90,7 @@ public class VisitController { } } - @RequestMapping(value = "/owners/*/pets/{petId}/visits", method = RequestMethod.GET) + @GetMapping("/owners/*/pets/{petId}/visits") public String showVisits(@PathVariable int petId, Map model) { model.put("visits", this.clinicService.findPetById(petId).getVisits()); return "visitList"; diff --git a/src/main/java/org/springframework/samples/petclinic/web/package-info.java b/src/main/java/org/springframework/samples/petclinic/web/package-info.java deleted file mode 100644 index c909ccf7f..000000000 --- a/src/main/java/org/springframework/samples/petclinic/web/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ - -/** - * - * The classes in this package represent PetClinic's web presentation layer. - * - */ -package org.springframework.samples.petclinic.web; - diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 000000000..025f89af9 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,22 @@ +# database init, supports mysql too +database=hsqldb +spring.datasource.schema=classpath*:db/${database}/schema.sql +spring.datasource.data=classpath*:db/${database}/data.sql + +# Web +spring.mvc.view.prefix=/WEB-INF/jsp/ +spring.mvc.view.suffix=.jsp + +# JPA +spring.jpa.hibernate.ddl-auto=none + +# Internationalization +spring.messages.basename=messages/messages + +# Actuator / Management +management.contextPath=/manage + +# Logging +logging.level.org.springframework=INFO + +server.context-path=/petclinic \ No newline at end of file diff --git a/src/main/resources/cache/ehcache.xml b/src/main/resources/cache/ehcache.xml deleted file mode 100644 index 32e509953..000000000 --- a/src/main/resources/cache/ehcache.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - diff --git a/src/main/resources/cache/ehcache.xsd b/src/main/resources/cache/ehcache.xsd deleted file mode 100644 index bfc19ddb1..000000000 --- a/src/main/resources/cache/ehcache.xsd +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/dandelion/datatables/datatables.properties b/src/main/resources/dandelion/datatables/datatables.properties deleted file mode 100644 index 08b1e439c..000000000 --- a/src/main/resources/dandelion/datatables/datatables.properties +++ /dev/null @@ -1,6 +0,0 @@ -# ================================== -# Dandelion-Datatables configuration -# ================================== - -# Disable the asset management of Dandelion-Core for all non-DataTable-related assets -main.standalone=true \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml deleted file mode 100644 index 830ef37de..000000000 --- a/src/main/resources/logback.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - true - - - - - - - - %-5level %logger{0} - %msg%n - - - - - - - - - - diff --git a/src/main/resources/spring/business-config.xml b/src/main/resources/spring/business-config.xml deleted file mode 100644 index 99cf4c1d3..000000000 --- a/src/main/resources/spring/business-config.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/spring/data-access.properties b/src/main/resources/spring/data-access.properties deleted file mode 100644 index c1cc3cefd..000000000 --- a/src/main/resources/spring/data-access.properties +++ /dev/null @@ -1,41 +0,0 @@ -# Properties file with JDBC and JPA settings. -# -# Applied by from -# various application context XML files (e.g., "applicationContext-*.xml"). -# Targeted at system administrators, to avoid touching the context XML files. - -#------------------------------------------------------------------------------- -# HSQL Settings - -jdbc.driverClassName=org.hsqldb.jdbcDriver -jdbc.url=jdbc:hsqldb:mem:petclinic -jdbc.username=sa -jdbc.password= - -# Properties that control the population of schema and data for a new data source -jdbc.initLocation=classpath:db/hsqldb/initDB.sql -jdbc.dataLocation=classpath:db/hsqldb/populateDB.sql - -# Property that determines which database to use with an AbstractJpaVendorAdapter -jpa.database=HSQL - -jpa.showSql=true - -#------------------------------------------------------------------------------- -# MySQL Settings - -#jdbc.driverClassName=com.mysql.jdbc.Driver -#jdbc.url=jdbc:mysql://localhost:3306/petclinic -#jdbc.username=root -#jdbc.password= - -# Properties that control the population of schema and data for a new data source -#jdbc.initLocation=classpath:db/mysql/initDB.sql -#jdbc.dataLocation=classpath:db/mysql/populateDB.sql - -# Property that determines which Hibernate dialect to use -# (only applied with "applicationContext-hibernate.xml") -#hibernate.dialect=org.hibernate.dialect.MySQLDialect - -# Property that determines which database to use with an AbstractJpaVendorAdapter -#jpa.database=MYSQL diff --git a/src/main/resources/spring/datasource-config.xml b/src/main/resources/spring/datasource-config.xml deleted file mode 100644 index f74129963..000000000 --- a/src/main/resources/spring/datasource-config.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/spring/mvc-core-config.xml b/src/main/resources/spring/mvc-core-config.xml deleted file mode 100644 index 51d2ce828..000000000 --- a/src/main/resources/spring/mvc-core-config.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/spring/mvc-view-config.xml b/src/main/resources/spring/mvc-view-config.xml deleted file mode 100644 index 190005f34..000000000 --- a/src/main/resources/spring/mvc-view-config.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - diff --git a/src/main/resources/spring/tools-config.xml b/src/main/resources/spring/tools-config.xml deleted file mode 100644 index 1be7e3b6c..000000000 --- a/src/main/resources/spring/tools-config.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index fb397e89d..000000000 --- a/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - Spring PetClinic - Spring PetClinic sample application - - - spring.profiles.active - jpa - - - - - - - - - - - contextConfigLocation - classpath:spring/business-config.xml, classpath:spring/tools-config.xml - - - - org.springframework.web.context.ContextLoaderListener - - - - - petclinic - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - classpath:spring/mvc-core-config.xml - - 1 - - - - petclinic - / - - - - - - - httpMethodFilter - org.springframework.web.filter.HiddenHttpMethodFilter - - - - httpMethodFilter - petclinic - - - - - encodingFilter - org.springframework.web.filter.CharacterEncodingFilter - - encoding - UTF-8 - - - forceEncoding - true - - - - - encodingFilter - /* - - - \ No newline at end of file diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index 44123baf8..e98ef1fe2 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -5,9 +5,8 @@ PetClinic :: a Spring Framework demonstration - - - + + @@ -20,9 +19,7 @@

-
-
diff --git a/src/main/webapp/resources/css/petclinic.css b/src/main/webapp/resources/css/petclinic.css index 76a8ef83d..e69de29bb 100644 --- a/src/main/webapp/resources/css/petclinic.css +++ b/src/main/webapp/resources/css/petclinic.css @@ -1,20 +0,0 @@ -.container { - padding-top: 10px; - width: 700px; -} - -.form-horizontal { - width: 100%; -} - -input[type="text"] { - height: 25px; -} - -.navbar .nav > li > a { - color: #000000; -} - -.form-horizontal .control-label { - text-align: left; -} diff --git a/src/main/webapp/scripts/app/fragments/bodyHeader.html b/src/main/webapp/scripts/app/fragments/bodyHeader.html index 8bdf23977..43faefce2 100644 --- a/src/main/webapp/scripts/app/fragments/bodyHeader.html +++ b/src/main/webapp/scripts/app/fragments/bodyHeader.html @@ -1,23 +1,24 @@ + \ No newline at end of file diff --git a/src/main/webapp/scripts/app/fragments/footer.html b/src/main/webapp/scripts/app/fragments/footer.html index 683e19cc2..7a64bc41b 100644 --- a/src/main/webapp/scripts/app/fragments/footer.html +++ b/src/main/webapp/scripts/app/fragments/footer.html @@ -1,11 +1,4 @@ - - - - - - - - +
+ Sponsored by Pivotal +
diff --git a/src/main/webapp/scripts/app/pet/PetController.js b/src/main/webapp/scripts/app/pet/PetController.js index a766a281c..a454a4448 100644 --- a/src/main/webapp/scripts/app/pet/PetController.js +++ b/src/main/webapp/scripts/app/pet/PetController.js @@ -1,13 +1,11 @@ 'use strict'; function loadPet($scope, $resource, $stateParams) { - var petResource = $resource('/petclinic/owner/' + $stateParams.ownerid +"/pet/" +$stateParams.petid); + var petResource = $resource('/petclinic/owner/' + $stateParams.ownerid +"/pet/" + $stateParams.petid); $scope.pet = petResource.get(); + $scope.types = $resource("/petclinic/petTypes").query(); } - - - /* * Form used to create and edit pets */ diff --git a/src/main/webapp/scripts/app/pet/petForm.html b/src/main/webapp/scripts/app/pet/petForm.html index d8aa79bdc..a1a090738 100644 --- a/src/main/webapp/scripts/app/pet/petForm.html +++ b/src/main/webapp/scripts/app/pet/petForm.html @@ -1,44 +1,38 @@ - - -
-

Pet (work in progress)

+

Pet

+
-
-
- - {{pet.owner.firstName}} {{pet.owner.lastName}} -
-
- - +
+ +
+

{{pet.owner}}

+
+
+ +
+ +
+ Name is required.
-
- - +
+ +
+ +
+ birth date is required.
- - -
-
-
- - - - - - - - + +
+ +
+ +
-
From a481ee4a8e0ffcd29502508fd878da064f4acac8 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 16:49:25 +0800 Subject: [PATCH 09/31] remove unrelated tests --- .../service/AbstractClinicServiceTests.java | 13 ++++--- .../service/ClinicServiceJdbcTests.java | 36 ------------------- .../service/ClinicServiceJpaTests.java | 23 ------------ .../ClinicServiceSpringDataJpaTests.java | 20 ----------- .../petclinic/service}/EntityUtils.java | 2 +- 5 files changed, 7 insertions(+), 87 deletions(-) delete mode 100644 src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJdbcTests.java delete mode 100644 src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJpaTests.java delete mode 100644 src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java rename src/{main/java/org/springframework/samples/petclinic/util => test/java/org/springframework/samples/petclinic/service}/EntityUtils.java (97%) diff --git a/src/test/java/org/springframework/samples/petclinic/service/AbstractClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/AbstractClinicServiceTests.java index b803af44e..330247ba4 100644 --- a/src/test/java/org/springframework/samples/petclinic/service/AbstractClinicServiceTests.java +++ b/src/test/java/org/springframework/samples/petclinic/service/AbstractClinicServiceTests.java @@ -15,11 +15,6 @@ */ package org.springframework.samples.petclinic.service; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Collection; - -import org.joda.time.DateTime; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.samples.petclinic.model.Owner; @@ -27,10 +22,14 @@ import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.model.Vet; import org.springframework.samples.petclinic.model.Visit; -import org.springframework.samples.petclinic.util.EntityUtils; import org.springframework.test.context.ContextConfiguration; import org.springframework.transaction.annotation.Transactional; +import java.util.Collection; +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; + /** *

Base class for {@link ClinicService} integration tests.

Subclasses should specify Spring context * configuration using {@link ContextConfiguration @ContextConfiguration} annotation

@@ -139,7 +138,7 @@ public abstract class AbstractClinicServiceTests { pet.setName("bowser"); Collection types = this.clinicService.findPetTypes(); pet.setType(EntityUtils.getById(types, PetType.class, 2)); - pet.setBirthDate(new DateTime()); + pet.setBirthDate(new Date()); owner6.addPet(pet); assertThat(owner6.getPets().size()).isEqualTo(found + 1); diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJdbcTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJdbcTests.java deleted file mode 100644 index 49e57ea40..000000000 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJdbcTests.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * 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.springframework.samples.petclinic.service; - -import org.junit.runner.RunWith; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - *

Integration test using the jdbc profile. - * @see AbstractClinicServiceTests AbstractClinicServiceTests for more details.

- * - * @author Thomas Risberg - * @author Michael Isvy - */ -@ContextConfiguration(locations = {"classpath:spring/business-config.xml"}) -@RunWith(SpringJUnit4ClassRunner.class) -@ActiveProfiles("jdbc") -public class ClinicServiceJdbcTests extends AbstractClinicServiceTests { - - -} diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJpaTests.java deleted file mode 100644 index e024f21fd..000000000 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceJpaTests.java +++ /dev/null @@ -1,23 +0,0 @@ - -package org.springframework.samples.petclinic.service; - -import org.junit.runner.RunWith; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - *

Integration test using the jpa profile. - * @see AbstractClinicServiceTests AbstractClinicServiceTests for more details.

- * - * @author Rod Johnson - * @author Sam Brannen - * @author Michael Isvy - */ - -@ContextConfiguration(locations = {"classpath:spring/business-config.xml"}) -@RunWith(SpringJUnit4ClassRunner.class) -@ActiveProfiles("jpa") -public class ClinicServiceJpaTests extends AbstractClinicServiceTests { - -} \ No newline at end of file diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java deleted file mode 100644 index e01dda551..000000000 --- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceSpringDataJpaTests.java +++ /dev/null @@ -1,20 +0,0 @@ - -package org.springframework.samples.petclinic.service; - -import org.junit.runner.RunWith; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - *

Integration test using the 'Spring Data' profile. - * @see AbstractClinicServiceTests AbstractClinicServiceTests for more details.

- * @author Michael Isvy - */ - -@ContextConfiguration(locations = {"classpath:spring/business-config.xml"}) -@RunWith(SpringJUnit4ClassRunner.class) -@ActiveProfiles("spring-data-jpa") -public class ClinicServiceSpringDataJpaTests extends AbstractClinicServiceTests { - -} \ No newline at end of file diff --git a/src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java b/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java similarity index 97% rename from src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java rename to src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java index a18f65c39..367aff37c 100644 --- a/src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java +++ b/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.samples.petclinic.util; +package org.springframework.samples.petclinic.service; import java.util.Collection; From c77f86a72d0e21ab4465c29d7c5d6f1376d4b0b2 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 17:10:49 +0800 Subject: [PATCH 10/31] update owner creation ui --- .../samples/petclinic/web/OwnerResource.java | 3 +- .../webapp/scripts/app/owner/ownerForm.html | 52 +++++++++++-------- .../scripts/app/owner/ownerSearchForm.html | 24 ++++----- 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java index e9cba805c..7024631ca 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java +++ b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java @@ -64,9 +64,8 @@ public class OwnerResource { */ @RequestMapping(value = "/owner", method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) - public void createOwner(@RequestBody Owner owner) { + public void createOwner(@Valid @RequestBody Owner owner) { this.clinicService.saveOwner(owner); - // TODO: need to handle failure } /** diff --git a/src/main/webapp/scripts/app/owner/ownerForm.html b/src/main/webapp/scripts/app/owner/ownerForm.html index 719c0af24..38177f549 100644 --- a/src/main/webapp/scripts/app/owner/ownerForm.html +++ b/src/main/webapp/scripts/app/owner/ownerForm.html @@ -1,37 +1,45 @@
-

Owner

-
-
- - +
+ +
+ First name is required.
-
- - +
+
+ +
+ Last name is required.
-
- - +
+
+ +
+ Address is required.
-
- - +
+
+ +
+ City is required.
-
- - +
+
+ +
+ Telephone is required.
- -
- -
-
+
+
+
+ +
+
diff --git a/src/main/webapp/scripts/app/owner/ownerSearchForm.html b/src/main/webapp/scripts/app/owner/ownerSearchForm.html index 548c452a8..4cd2fac2d 100644 --- a/src/main/webapp/scripts/app/owner/ownerSearchForm.html +++ b/src/main/webapp/scripts/app/owner/ownerSearchForm.html @@ -1,15 +1,9 @@ -

Find Owners

-
-
-
- - -
-
- -
-
-
- -
- Add Owners +

Owners

+
+
+ + + | + Add New Owner +
+
\ No newline at end of file From b3db40a2666119a179eec6f9456dabf970fe2836 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Mon, 19 Sep 2016 17:11:29 +0800 Subject: [PATCH 11/31] update owner creation ui --- .../org/springframework/samples/petclinic/web/OwnerResource.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java index 7024631ca..073cf80a9 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java +++ b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java @@ -109,7 +109,6 @@ public class OwnerResource { ownerModel.setTelephone(ownerRequest.getTelephone()); this.clinicService.saveOwner(ownerModel); return ownerModel; - // TODO: need to handle failure } From 3510dbfc4522f7cfc933519806625024be871a89 Mon Sep 17 00:00:00 2001 From: Dapeng Date: Tue, 20 Sep 2016 11:41:05 +0800 Subject: [PATCH 12/31] ui update 1. upgrade angular version to 1.5.8 2. upgrade bootstrap to 3 3. fix ui integrations up to visits 4. move to webjars --- pom.xml | 12 + .../petclinic/repository/OwnerRepository.java | 30 +- .../petclinic/service/ClinicService.java | 17 +- .../petclinic/service/ClinicServiceImpl.java | 7 +- .../samples/petclinic/web/OwnerResource.java | 19 +- .../samples/petclinic/web/PetResource.java | 83 +- .../jsp/pets/createOrUpdateVisitForm.jsp | 73 - .../WEB-INF/no-spring-config-files-there.txt | 4 - src/main/webapp/WEB-INF/tags/inputField.tag | 19 - src/main/webapp/WEB-INF/tags/selectField.tag | 23 - .../angular-mocks/.bower.json | 19 - .../bower_components/angular-mocks/README.md | 57 - .../angular-mocks/angular-mocks.js | 2382 - .../bower_components/angular-mocks/bower.json | 9 - .../angular-mocks/package.json | 27 - .../angular-resource/.bower.json | 19 - .../angular-resource/README.md | 77 - .../angular-resource/angular-resource.js | 667 - .../angular-resource/angular-resource.min.js | 13 - .../angular-resource.min.js.map | 8 - .../angular-resource/bower.json | 9 - .../angular-resource/package.json | 26 - .../angular-scenario/.bower.json | 19 - .../angular-scenario/README.md | 61 - .../angular-scenario/angular-scenario.js | 37470 ---------------- .../angular-scenario/bower.json | 9 - .../jstd-scenario-adapter-config.js | 6 - .../angular-scenario/jstd-scenario-adapter.js | 185 - .../angular-scenario/package.json | 26 - .../angular-ui-router/.bower.json | 33 - .../angular-ui-router/CHANGELOG.md | 228 - .../angular-ui-router/CONTRIBUTING.md | 65 - .../angular-ui-router/LICENSE | 21 - .../angular-ui-router/README.md | 245 - .../api/angular-ui-router.d.ts | 126 - .../angular-ui-router/bower.json | 23 - .../release/angular-ui-router.js | 4370 -- .../release/angular-ui-router.min.js | 7 - .../angular-ui-router/src/common.js | 292 - .../angular-ui-router/src/resolve.js | 252 - .../angular-ui-router/src/state.js | 1465 - .../angular-ui-router/src/stateDirectives.js | 285 - .../angular-ui-router/src/stateFilters.js | 39 - .../angular-ui-router/src/templateFactory.js | 110 - .../src/urlMatcherFactory.js | 1050 - .../angular-ui-router/src/urlRouter.js | 427 - .../angular-ui-router/src/view.js | 71 - .../angular-ui-router/src/viewDirective.js | 303 - .../angular-ui-router/src/viewScroll.js | 52 - .../bower_components/angular/.bower.json | 17 - .../webapp/bower_components/angular/README.md | 67 - .../bower_components/angular/angular-csp.css | 13 - .../bower_components/angular/angular.js | 26116 ----------- .../bower_components/angular/angular.min.js | 251 - .../angular/angular.min.js.gzip | Bin 45987 -> 0 bytes .../angular/angular.min.js.map | 8 - .../bower_components/angular/bower.json | 8 - .../bower_components/angular/package.json | 25 - .../bower_components/bootstrap/.bower.json | 21 - .../bower_components/bootstrap/.gitignore | 37 - .../bower_components/bootstrap/.travis.yml | 3 - .../bower_components/bootstrap/CHANGELOG.md | 350 - .../bootstrap/CONTRIBUTING.md | 75 - .../webapp/bower_components/bootstrap/LICENSE | 176 - .../bower_components/bootstrap/Makefile | 126 - .../bower_components/bootstrap/README.md | 116 - .../bower_components/bootstrap/component.json | 8 - .../bower_components/bootstrap/composer.json | 9 - .../docs/assets/css/bootstrap-responsive.css | 1109 - .../bootstrap/docs/assets/css/bootstrap.css | 6158 --- .../bootstrap/docs/assets/css/docs.css | 1067 - .../ico/apple-touch-icon-114-precomposed.png | Bin 11392 -> 0 bytes .../ico/apple-touch-icon-144-precomposed.png | Bin 16780 -> 0 bytes .../ico/apple-touch-icon-57-precomposed.png | Bin 4026 -> 0 bytes .../ico/apple-touch-icon-72-precomposed.png | Bin 5681 -> 0 bytes .../bootstrap/docs/assets/ico/favicon.ico | Bin 1150 -> 0 bytes .../bootstrap/docs/assets/ico/favicon.png | Bin 2711 -> 0 bytes .../docs/assets/img/bootstrap-docs-readme.png | Bin 30612 -> 0 bytes .../assets/img/bootstrap-mdo-sfmoma-01.jpg | Bin 125346 -> 0 bytes .../assets/img/bootstrap-mdo-sfmoma-02.jpg | Bin 81284 -> 0 bytes .../assets/img/bootstrap-mdo-sfmoma-03.jpg | Bin 49063 -> 0 bytes .../assets/img/bs-docs-bootstrap-features.png | Bin 11244 -> 0 bytes .../assets/img/bs-docs-masthead-pattern.png | Bin 6450 -> 0 bytes .../img/bs-docs-responsive-illustrations.png | Bin 10572 -> 0 bytes .../assets/img/bs-docs-twitter-github.png | Bin 30968 -> 0 bytes .../assets/img/example-sites/8020select.png | Bin 62853 -> 0 bytes .../img/example-sites/adoptahydrant.png | Bin 136480 -> 0 bytes .../assets/img/example-sites/breakingnews.png | Bin 72725 -> 0 bytes .../docs/assets/img/example-sites/fleetio.png | Bin 39837 -> 0 bytes .../img/example-sites/gathercontent.png | Bin 76560 -> 0 bytes .../docs/assets/img/example-sites/jshint.png | Bin 7258 -> 0 bytes .../docs/assets/img/example-sites/kippt.png | Bin 48259 -> 0 bytes .../assets/img/example-sites/soundready.png | Bin 50225 -> 0 bytes .../examples/bootstrap-example-carousel.png | Bin 339980 -> 0 bytes .../img/examples/bootstrap-example-fluid.png | Bin 209039 -> 0 bytes .../bootstrap-example-justified-nav.png | Bin 136021 -> 0 bytes .../bootstrap-example-marketing-narrow.png | Bin 117303 -> 0 bytes .../examples/bootstrap-example-marketing.png | Bin 134269 -> 0 bytes .../img/examples/bootstrap-example-signin.png | Bin 22037 -> 0 bytes .../examples/bootstrap-example-starter.png | Bin 36099 -> 0 bytes .../bootstrap-example-sticky-footer.png | Bin 30820 -> 0 bytes .../img/examples/browser-icon-chrome.png | Bin 55522 -> 0 bytes .../img/examples/browser-icon-firefox.png | Bin 175994 -> 0 bytes .../img/examples/browser-icon-safari.png | Bin 209527 -> 0 bytes .../docs/assets/img/examples/slide-01.jpg | Bin 83303 -> 0 bytes .../docs/assets/img/examples/slide-02.jpg | Bin 137070 -> 0 bytes .../docs/assets/img/examples/slide-03.jpg | Bin 137378 -> 0 bytes .../assets/img/glyphicons-halflings-white.png | Bin 8777 -> 0 bytes .../docs/assets/img/glyphicons-halflings.png | Bin 12799 -> 0 bytes .../docs/assets/img/grid-baseline-20px.png | Bin 84 -> 0 bytes .../docs/assets/img/less-logo-large.png | Bin 12824 -> 0 bytes .../assets/img/responsive-illustrations.png | Bin 1008 -> 0 bytes .../bootstrap/docs/assets/js/README.md | 106 - .../bootstrap/docs/assets/js/application.js | 156 - .../docs/assets/js/bootstrap-affix.js | 117 - .../docs/assets/js/bootstrap-alert.js | 99 - .../docs/assets/js/bootstrap-button.js | 105 - .../docs/assets/js/bootstrap-carousel.js | 207 - .../docs/assets/js/bootstrap-collapse.js | 167 - .../docs/assets/js/bootstrap-dropdown.js | 165 - .../docs/assets/js/bootstrap-modal.js | 247 - .../docs/assets/js/bootstrap-popover.js | 114 - .../docs/assets/js/bootstrap-scrollspy.js | 162 - .../bootstrap/docs/assets/js/bootstrap-tab.js | 144 - .../docs/assets/js/bootstrap-tooltip.js | 353 - .../docs/assets/js/bootstrap-transition.js | 60 - .../docs/assets/js/bootstrap-typeahead.js | 335 - .../bootstrap/docs/assets/js/bootstrap.js | 2268 - .../bootstrap/docs/assets/js/bootstrap.min.js | 6 - .../js/google-code-prettify/prettify.css | 30 - .../js/google-code-prettify/prettify.js | 28 - .../bootstrap/docs/assets/js/holder/holder.js | 401 - .../bootstrap/docs/assets/js/html5shiv.js | 8 - .../bootstrap/docs/assets/js/jquery.js | 5 - .../bootstrap/docs/base-css.html | 2215 - .../bootstrap/docs/build/index.js | 44 - .../bootstrap/docs/build/package.json | 6 - .../bootstrap/docs/components.html | 2626 -- .../bootstrap/docs/customize.html | 514 - .../bootstrap/docs/examples/carousel.html | 454 - .../bootstrap/docs/examples/fluid.html | 163 - .../bootstrap/docs/examples/hero.html | 126 - .../docs/examples/justified-nav.html | 174 - .../docs/examples/marketing-narrow.html | 137 - .../bootstrap/docs/examples/signin.html | 94 - .../docs/examples/starter-template.html | 79 - .../docs/examples/sticky-footer-navbar.html | 161 - .../docs/examples/sticky-footer.html | 125 - .../bootstrap/docs/extend.html | 282 - .../bootstrap/docs/getting-started.html | 377 - .../bootstrap/docs/index.html | 221 - .../bootstrap/docs/javascript.html | 1780 - .../bootstrap/docs/scaffolding.html | 602 - .../bootstrap/docs/templates/layout.mustache | 151 - .../docs/templates/pages/base-css.mustache | 2102 - .../docs/templates/pages/components.mustache | 2505 -- .../docs/templates/pages/customize.mustache | 393 - .../docs/templates/pages/extend.mustache | 161 - .../templates/pages/getting-started.mustache | 256 - .../docs/templates/pages/index.mustache | 100 - .../docs/templates/pages/javascript.mustache | 1660 - .../docs/templates/pages/scaffolding.mustache | 485 - .../img/glyphicons-halflings-white.png | Bin 8777 -> 0 bytes .../bootstrap/img/glyphicons-halflings.png | Bin 12799 -> 0 bytes .../bower_components/bootstrap/js/.jshintrc | 12 - .../bootstrap/js/bootstrap-affix.js | 117 - .../bootstrap/js/bootstrap-alert.js | 99 - .../bootstrap/js/bootstrap-button.js | 105 - .../bootstrap/js/bootstrap-carousel.js | 207 - .../bootstrap/js/bootstrap-collapse.js | 167 - .../bootstrap/js/bootstrap-dropdown.js | 165 - .../bootstrap/js/bootstrap-modal.js | 247 - .../bootstrap/js/bootstrap-popover.js | 114 - .../bootstrap/js/bootstrap-scrollspy.js | 162 - .../bootstrap/js/bootstrap-tab.js | 144 - .../bootstrap/js/bootstrap-tooltip.js | 353 - .../bootstrap/js/bootstrap-transition.js | 60 - .../bootstrap/js/bootstrap-typeahead.js | 335 - .../bootstrap/js/tests/index.html | 56 - .../bootstrap/js/tests/phantom.js | 63 - .../bootstrap/js/tests/server.js | 14 - .../js/tests/unit/bootstrap-affix.js | 25 - .../js/tests/unit/bootstrap-alert.js | 62 - .../js/tests/unit/bootstrap-button.js | 102 - .../js/tests/unit/bootstrap-carousel.js | 81 - .../js/tests/unit/bootstrap-collapse.js | 94 - .../js/tests/unit/bootstrap-dropdown.js | 151 - .../js/tests/unit/bootstrap-modal.js | 120 - .../js/tests/unit/bootstrap-phantom.js | 21 - .../js/tests/unit/bootstrap-popover.js | 113 - .../js/tests/unit/bootstrap-scrollspy.js | 37 - .../bootstrap/js/tests/unit/bootstrap-tab.js | 86 - .../js/tests/unit/bootstrap-tooltip.js | 294 - .../js/tests/unit/bootstrap-transition.js | 13 - .../js/tests/unit/bootstrap-typeahead.js | 236 - .../bootstrap/js/tests/vendor/jquery.js | 5 - .../bootstrap/js/tests/vendor/qunit.css | 232 - .../bootstrap/js/tests/vendor/qunit.js | 1510 - .../bootstrap/less/accordion.less | 34 - .../bootstrap/less/alerts.less | 79 - .../bootstrap/less/bootstrap.less | 63 - .../bootstrap/less/breadcrumbs.less | 24 - .../bootstrap/less/button-groups.less | 229 - .../bootstrap/less/buttons.less | 228 - .../bootstrap/less/carousel.less | 158 - .../bootstrap/less/close.less | 32 - .../bower_components/bootstrap/less/code.less | 61 - .../bootstrap/less/component-animations.less | 22 - .../bootstrap/less/dropdowns.less | 237 - .../bootstrap/less/forms.less | 690 - .../bower_components/bootstrap/less/grid.less | 21 - .../bootstrap/less/hero-unit.less | 25 - .../bootstrap/less/labels-badges.less | 84 - .../bootstrap/less/layouts.less | 16 - .../bootstrap/less/media.less | 55 - .../bootstrap/less/mixins.less | 702 - .../bootstrap/less/modals.less | 95 - .../bootstrap/less/navbar.less | 497 - .../bower_components/bootstrap/less/navs.less | 409 - .../bootstrap/less/pager.less | 43 - .../bootstrap/less/pagination.less | 123 - .../bootstrap/less/popovers.less | 133 - .../bootstrap/less/progress-bars.less | 122 - .../bootstrap/less/reset.less | 216 - .../bootstrap/less/responsive-1200px-min.less | 28 - .../bootstrap/less/responsive-767px-max.less | 193 - .../less/responsive-768px-979px.less | 19 - .../bootstrap/less/responsive-navbar.less | 189 - .../bootstrap/less/responsive-utilities.less | 59 - .../bootstrap/less/responsive.less | 48 - .../bootstrap/less/scaffolding.less | 53 - .../bootstrap/less/sprites.less | 197 - .../bootstrap/less/tables.less | 244 - .../bootstrap/less/tests/buttons.html | 139 - .../bootstrap/less/tests/css-tests.css | 150 - .../bootstrap/less/tests/css-tests.html | 1399 - .../less/tests/forms-responsive.html | 71 - .../bootstrap/less/tests/forms.html | 179 - .../less/tests/navbar-fixed-top.html | 104 - .../less/tests/navbar-static-top.html | 107 - .../bootstrap/less/tests/navbar.html | 107 - .../bootstrap/less/thumbnails.less | 53 - .../bootstrap/less/tooltip.less | 70 - .../bower_components/bootstrap/less/type.less | 247 - .../bootstrap/less/utilities.less | 30 - .../bootstrap/less/variables.less | 301 - .../bootstrap/less/wells.less | 29 - .../bower_components/bootstrap/package.json | 26 - .../bower_components/jquery/.bower.json | 37 - .../bower_components/jquery/MIT-LICENSE.txt | 21 - .../webapp/bower_components/jquery/bower.json | 27 - .../bower_components/jquery/dist/jquery.js | 9205 ---- .../jquery/dist/jquery.min.js | 5 - .../jquery/dist/jquery.min.map | 1 - .../bower_components/jquery/src/ajax.js | 786 - .../bower_components/jquery/src/ajax/jsonp.js | 89 - .../bower_components/jquery/src/ajax/load.js | 75 - .../jquery/src/ajax/parseJSON.js | 13 - .../jquery/src/ajax/parseXML.js | 28 - .../jquery/src/ajax/script.js | 64 - .../jquery/src/ajax/var/nonce.js | 5 - .../jquery/src/ajax/var/rquery.js | 3 - .../bower_components/jquery/src/ajax/xhr.js | 136 - .../bower_components/jquery/src/attributes.js | 11 - .../jquery/src/attributes/attr.js | 141 - .../jquery/src/attributes/classes.js | 158 - .../jquery/src/attributes/prop.js | 94 - .../jquery/src/attributes/support.js | 35 - .../jquery/src/attributes/val.js | 161 - .../bower_components/jquery/src/callbacks.js | 205 - .../bower_components/jquery/src/core.js | 497 - .../jquery/src/core/access.js | 60 - .../bower_components/jquery/src/core/init.js | 123 - .../jquery/src/core/parseHTML.js | 39 - .../bower_components/jquery/src/core/ready.js | 97 - .../jquery/src/core/var/rsingleTag.js | 4 - .../webapp/bower_components/jquery/src/css.js | 450 - .../jquery/src/css/addGetHookIf.js | 22 - .../bower_components/jquery/src/css/curCSS.js | 57 - .../jquery/src/css/defaultDisplay.js | 70 - .../jquery/src/css/hiddenVisibleSelectors.js | 15 - .../jquery/src/css/support.js | 96 - .../bower_components/jquery/src/css/swap.js | 28 - .../jquery/src/css/var/cssExpand.js | 3 - .../jquery/src/css/var/getStyles.js | 12 - .../jquery/src/css/var/isHidden.js | 13 - .../jquery/src/css/var/rmargin.js | 3 - .../jquery/src/css/var/rnumnonpx.js | 5 - .../bower_components/jquery/src/data.js | 178 - .../bower_components/jquery/src/data/Data.js | 181 - .../jquery/src/data/accepts.js | 20 - .../jquery/src/data/var/data_priv.js | 5 - .../jquery/src/data/var/data_user.js | 5 - .../bower_components/jquery/src/deferred.js | 149 - .../bower_components/jquery/src/deprecated.js | 13 - .../bower_components/jquery/src/dimensions.js | 50 - .../bower_components/jquery/src/effects.js | 648 - .../jquery/src/effects/Tween.js | 114 - .../jquery/src/effects/animatedSelector.js | 13 - .../bower_components/jquery/src/event.js | 868 - .../bower_components/jquery/src/event/ajax.js | 13 - .../jquery/src/event/alias.js | 39 - .../jquery/src/event/support.js | 9 - .../jquery/src/exports/amd.js | 24 - .../jquery/src/exports/global.js | 32 - .../bower_components/jquery/src/intro.js | 44 - .../bower_components/jquery/src/jquery.js | 37 - .../jquery/src/manipulation.js | 580 - .../jquery/src/manipulation/_evalUrl.js | 18 - .../jquery/src/manipulation/support.js | 32 - .../src/manipulation/var/rcheckableType.js | 3 - .../bower_components/jquery/src/offset.js | 207 - .../bower_components/jquery/src/outro.js | 1 - .../bower_components/jquery/src/queue.js | 142 - .../jquery/src/queue/delay.js | 22 - .../jquery/src/selector-native.js | 172 - .../jquery/src/selector-sizzle.js | 14 - .../bower_components/jquery/src/selector.js | 1 - .../bower_components/jquery/src/serialize.js | 111 - .../jquery/src/sizzle/dist/sizzle.js | 2067 - .../jquery/src/sizzle/dist/sizzle.min.js | 3 - .../jquery/src/sizzle/dist/sizzle.min.map | 1 - .../bower_components/jquery/src/traversing.js | 199 - .../jquery/src/traversing/findFilter.js | 100 - .../src/traversing/var/rneedsContext.js | 6 - .../bower_components/jquery/src/var/arr.js | 3 - .../jquery/src/var/class2type.js | 4 - .../bower_components/jquery/src/var/concat.js | 5 - .../bower_components/jquery/src/var/hasOwn.js | 5 - .../jquery/src/var/indexOf.js | 5 - .../bower_components/jquery/src/var/pnum.js | 3 - .../bower_components/jquery/src/var/push.js | 5 - .../jquery/src/var/rnotwhite.js | 3 - .../bower_components/jquery/src/var/slice.js | 5 - .../jquery/src/var/strundefined.js | 3 - .../jquery/src/var/support.js | 4 - .../jquery/src/var/toString.js | 5 - .../bower_components/jquery/src/wrap.js | 79 - .../webapp/bower_components/json3/.bower.json | 47 - .../bower_components/json3/CHANGELOG.md | 44 - .../bower_components/json3/CONTRIBUTING.md | 3 - .../webapp/bower_components/json3/LICENSE | 20 - .../webapp/bower_components/json3/README.md | 152 - .../webapp/bower_components/json3/bower.json | 38 - .../bower_components/json3/lib/json3.js | 902 - .../bower_components/json3/lib/json3.min.js | 17 - src/main/webapp/index.html | 46 +- src/main/webapp/scripts/app/app.js | 140 +- .../scripts/app/fragments/bodyHeader.html | 24 - .../webapp/scripts/app/fragments/footer.html | 2 +- .../webapp/scripts/app/fragments/nav.html | 30 + .../webapp/scripts/app/fragments/welcome.html | 1 + .../webapp/scripts/app/main/MainController.js | 9 - src/main/webapp/scripts/app/main/main.html | 3 - .../owner-details/owner-details.component.js | 16 + .../owner-details/owner-details.template.html | 69 + .../app/owner-form/owner-form.component.js | 41 + .../app/owner-form/owner-form.template.html | 44 + .../{owner => owner-list}/OwnerController.js | 2 - .../app/owner-list/owner-list.component.js | 15 + .../app/owner-list/owner-list.template.html | 24 + .../{owner => owner-list}/ownerDetail.html | 0 .../app/{owner => owner-list}/ownerForm.html | 0 .../ownerSearchForm.html | 0 .../webapp/scripts/app/owner/ownerList.html | 26 - .../app/pet-form/pet-form.component.js | 63 + .../app/pet-form/pet-form.template.html | 43 + .../app/vet-list/vet-list.component.js | 16 + .../app/vet-list/vet-list.template.html | 15 + .../webapp/scripts/app/vet/VetController.js | 13 - src/main/webapp/scripts/app/vet/vetList.html | 16 - .../service/AbstractClinicServiceTests.java | 18 +- 372 files changed, 522 insertions(+), 144439 deletions(-) delete mode 100644 src/main/webapp/WEB-INF/jsp/pets/createOrUpdateVisitForm.jsp delete mode 100644 src/main/webapp/WEB-INF/no-spring-config-files-there.txt delete mode 100644 src/main/webapp/WEB-INF/tags/inputField.tag delete mode 100644 src/main/webapp/WEB-INF/tags/selectField.tag delete mode 100644 src/main/webapp/bower_components/angular-mocks/.bower.json delete mode 100644 src/main/webapp/bower_components/angular-mocks/README.md delete mode 100644 src/main/webapp/bower_components/angular-mocks/angular-mocks.js delete mode 100644 src/main/webapp/bower_components/angular-mocks/bower.json delete mode 100644 src/main/webapp/bower_components/angular-mocks/package.json delete mode 100644 src/main/webapp/bower_components/angular-resource/.bower.json delete mode 100644 src/main/webapp/bower_components/angular-resource/README.md delete mode 100644 src/main/webapp/bower_components/angular-resource/angular-resource.js delete mode 100644 src/main/webapp/bower_components/angular-resource/angular-resource.min.js delete mode 100644 src/main/webapp/bower_components/angular-resource/angular-resource.min.js.map delete mode 100644 src/main/webapp/bower_components/angular-resource/bower.json delete mode 100644 src/main/webapp/bower_components/angular-resource/package.json delete mode 100644 src/main/webapp/bower_components/angular-scenario/.bower.json delete mode 100644 src/main/webapp/bower_components/angular-scenario/README.md delete mode 100644 src/main/webapp/bower_components/angular-scenario/angular-scenario.js delete mode 100644 src/main/webapp/bower_components/angular-scenario/bower.json delete mode 100644 src/main/webapp/bower_components/angular-scenario/jstd-scenario-adapter-config.js delete mode 100644 src/main/webapp/bower_components/angular-scenario/jstd-scenario-adapter.js delete mode 100644 src/main/webapp/bower_components/angular-scenario/package.json delete mode 100644 src/main/webapp/bower_components/angular-ui-router/.bower.json delete mode 100644 src/main/webapp/bower_components/angular-ui-router/CHANGELOG.md delete mode 100644 src/main/webapp/bower_components/angular-ui-router/CONTRIBUTING.md delete mode 100644 src/main/webapp/bower_components/angular-ui-router/LICENSE delete mode 100644 src/main/webapp/bower_components/angular-ui-router/README.md delete mode 100644 src/main/webapp/bower_components/angular-ui-router/api/angular-ui-router.d.ts delete mode 100644 src/main/webapp/bower_components/angular-ui-router/bower.json delete mode 100644 src/main/webapp/bower_components/angular-ui-router/release/angular-ui-router.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/release/angular-ui-router.min.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/common.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/resolve.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/state.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/stateDirectives.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/stateFilters.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/templateFactory.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/urlMatcherFactory.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/urlRouter.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/view.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/viewDirective.js delete mode 100644 src/main/webapp/bower_components/angular-ui-router/src/viewScroll.js delete mode 100644 src/main/webapp/bower_components/angular/.bower.json delete mode 100644 src/main/webapp/bower_components/angular/README.md delete mode 100644 src/main/webapp/bower_components/angular/angular-csp.css delete mode 100644 src/main/webapp/bower_components/angular/angular.js delete mode 100644 src/main/webapp/bower_components/angular/angular.min.js delete mode 100644 src/main/webapp/bower_components/angular/angular.min.js.gzip delete mode 100644 src/main/webapp/bower_components/angular/angular.min.js.map delete mode 100644 src/main/webapp/bower_components/angular/bower.json delete mode 100644 src/main/webapp/bower_components/angular/package.json delete mode 100644 src/main/webapp/bower_components/bootstrap/.bower.json delete mode 100644 src/main/webapp/bower_components/bootstrap/.gitignore delete mode 100644 src/main/webapp/bower_components/bootstrap/.travis.yml delete mode 100644 src/main/webapp/bower_components/bootstrap/CHANGELOG.md delete mode 100644 src/main/webapp/bower_components/bootstrap/CONTRIBUTING.md delete mode 100644 src/main/webapp/bower_components/bootstrap/LICENSE delete mode 100644 src/main/webapp/bower_components/bootstrap/Makefile delete mode 100644 src/main/webapp/bower_components/bootstrap/README.md delete mode 100644 src/main/webapp/bower_components/bootstrap/component.json delete mode 100644 src/main/webapp/bower_components/bootstrap/composer.json delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/css/bootstrap.css delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/css/docs.css delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/ico/apple-touch-icon-114-precomposed.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/ico/apple-touch-icon-144-precomposed.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/ico/apple-touch-icon-57-precomposed.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/ico/apple-touch-icon-72-precomposed.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/ico/favicon.ico delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/ico/favicon.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/bootstrap-docs-readme.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/bootstrap-mdo-sfmoma-01.jpg delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/bootstrap-mdo-sfmoma-02.jpg delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/bootstrap-mdo-sfmoma-03.jpg delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/bs-docs-bootstrap-features.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/bs-docs-masthead-pattern.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/bs-docs-responsive-illustrations.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/bs-docs-twitter-github.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/example-sites/8020select.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/example-sites/adoptahydrant.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/example-sites/breakingnews.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/example-sites/fleetio.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/example-sites/gathercontent.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/example-sites/jshint.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/example-sites/kippt.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/example-sites/soundready.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/bootstrap-example-carousel.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/bootstrap-example-fluid.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/bootstrap-example-justified-nav.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/bootstrap-example-marketing-narrow.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/bootstrap-example-marketing.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/bootstrap-example-signin.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/bootstrap-example-starter.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/bootstrap-example-sticky-footer.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/browser-icon-chrome.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/browser-icon-firefox.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/browser-icon-safari.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/slide-01.jpg delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/slide-02.jpg delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/examples/slide-03.jpg delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/glyphicons-halflings-white.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/glyphicons-halflings.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/grid-baseline-20px.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/less-logo-large.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/img/responsive-illustrations.png delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/README.md delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/application.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-affix.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-alert.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-button.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-carousel.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-collapse.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-dropdown.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-modal.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-popover.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-scrollspy.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-tab.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-tooltip.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-transition.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap-typeahead.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/bootstrap.min.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/google-code-prettify/prettify.css delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/google-code-prettify/prettify.js delete mode 100755 src/main/webapp/bower_components/bootstrap/docs/assets/js/holder/holder.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/html5shiv.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/assets/js/jquery.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/base-css.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/build/index.js delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/build/package.json delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/components.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/customize.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/carousel.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/fluid.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/hero.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/justified-nav.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/marketing-narrow.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/signin.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/starter-template.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/sticky-footer-navbar.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/examples/sticky-footer.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/extend.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/getting-started.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/index.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/javascript.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/scaffolding.html delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/layout.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/pages/base-css.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/pages/components.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/pages/customize.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/pages/extend.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/pages/getting-started.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/pages/index.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/pages/javascript.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/docs/templates/pages/scaffolding.mustache delete mode 100644 src/main/webapp/bower_components/bootstrap/img/glyphicons-halflings-white.png delete mode 100644 src/main/webapp/bower_components/bootstrap/img/glyphicons-halflings.png delete mode 100644 src/main/webapp/bower_components/bootstrap/js/.jshintrc delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-affix.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-alert.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-button.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-carousel.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-collapse.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-dropdown.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-modal.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-popover.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-scrollspy.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-tab.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-tooltip.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-transition.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/bootstrap-typeahead.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/index.html delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/phantom.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/server.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-affix.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-alert.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-button.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-carousel.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-collapse.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-dropdown.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-modal.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-phantom.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-popover.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-scrollspy.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-tab.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-tooltip.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-transition.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/unit/bootstrap-typeahead.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/vendor/jquery.js delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/vendor/qunit.css delete mode 100644 src/main/webapp/bower_components/bootstrap/js/tests/vendor/qunit.js delete mode 100644 src/main/webapp/bower_components/bootstrap/less/accordion.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/alerts.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/bootstrap.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/breadcrumbs.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/button-groups.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/buttons.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/carousel.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/close.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/code.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/component-animations.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/dropdowns.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/forms.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/grid.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/hero-unit.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/labels-badges.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/layouts.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/media.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/mixins.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/modals.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/navbar.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/navs.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/pager.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/pagination.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/popovers.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/progress-bars.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/reset.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/responsive-1200px-min.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/responsive-767px-max.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/responsive-768px-979px.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/responsive-navbar.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/responsive-utilities.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/responsive.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/scaffolding.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/sprites.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tables.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tests/buttons.html delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tests/css-tests.css delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tests/css-tests.html delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tests/forms-responsive.html delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tests/forms.html delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tests/navbar-fixed-top.html delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tests/navbar-static-top.html delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tests/navbar.html delete mode 100644 src/main/webapp/bower_components/bootstrap/less/thumbnails.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/tooltip.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/type.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/utilities.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/variables.less delete mode 100644 src/main/webapp/bower_components/bootstrap/less/wells.less delete mode 100644 src/main/webapp/bower_components/bootstrap/package.json delete mode 100644 src/main/webapp/bower_components/jquery/.bower.json delete mode 100644 src/main/webapp/bower_components/jquery/MIT-LICENSE.txt delete mode 100644 src/main/webapp/bower_components/jquery/bower.json delete mode 100644 src/main/webapp/bower_components/jquery/dist/jquery.js delete mode 100644 src/main/webapp/bower_components/jquery/dist/jquery.min.js delete mode 100644 src/main/webapp/bower_components/jquery/dist/jquery.min.map delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax.js delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax/jsonp.js delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax/load.js delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax/parseJSON.js delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax/parseXML.js delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax/script.js delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax/var/nonce.js delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax/var/rquery.js delete mode 100644 src/main/webapp/bower_components/jquery/src/ajax/xhr.js delete mode 100644 src/main/webapp/bower_components/jquery/src/attributes.js delete mode 100644 src/main/webapp/bower_components/jquery/src/attributes/attr.js delete mode 100644 src/main/webapp/bower_components/jquery/src/attributes/classes.js delete mode 100644 src/main/webapp/bower_components/jquery/src/attributes/prop.js delete mode 100644 src/main/webapp/bower_components/jquery/src/attributes/support.js delete mode 100644 src/main/webapp/bower_components/jquery/src/attributes/val.js delete mode 100644 src/main/webapp/bower_components/jquery/src/callbacks.js delete mode 100644 src/main/webapp/bower_components/jquery/src/core.js delete mode 100644 src/main/webapp/bower_components/jquery/src/core/access.js delete mode 100644 src/main/webapp/bower_components/jquery/src/core/init.js delete mode 100644 src/main/webapp/bower_components/jquery/src/core/parseHTML.js delete mode 100644 src/main/webapp/bower_components/jquery/src/core/ready.js delete mode 100644 src/main/webapp/bower_components/jquery/src/core/var/rsingleTag.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/addGetHookIf.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/curCSS.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/defaultDisplay.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/hiddenVisibleSelectors.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/support.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/swap.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/var/cssExpand.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/var/getStyles.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/var/isHidden.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/var/rmargin.js delete mode 100644 src/main/webapp/bower_components/jquery/src/css/var/rnumnonpx.js delete mode 100644 src/main/webapp/bower_components/jquery/src/data.js delete mode 100644 src/main/webapp/bower_components/jquery/src/data/Data.js delete mode 100644 src/main/webapp/bower_components/jquery/src/data/accepts.js delete mode 100644 src/main/webapp/bower_components/jquery/src/data/var/data_priv.js delete mode 100644 src/main/webapp/bower_components/jquery/src/data/var/data_user.js delete mode 100644 src/main/webapp/bower_components/jquery/src/deferred.js delete mode 100644 src/main/webapp/bower_components/jquery/src/deprecated.js delete mode 100644 src/main/webapp/bower_components/jquery/src/dimensions.js delete mode 100644 src/main/webapp/bower_components/jquery/src/effects.js delete mode 100644 src/main/webapp/bower_components/jquery/src/effects/Tween.js delete mode 100644 src/main/webapp/bower_components/jquery/src/effects/animatedSelector.js delete mode 100644 src/main/webapp/bower_components/jquery/src/event.js delete mode 100644 src/main/webapp/bower_components/jquery/src/event/ajax.js delete mode 100644 src/main/webapp/bower_components/jquery/src/event/alias.js delete mode 100644 src/main/webapp/bower_components/jquery/src/event/support.js delete mode 100644 src/main/webapp/bower_components/jquery/src/exports/amd.js delete mode 100644 src/main/webapp/bower_components/jquery/src/exports/global.js delete mode 100644 src/main/webapp/bower_components/jquery/src/intro.js delete mode 100644 src/main/webapp/bower_components/jquery/src/jquery.js delete mode 100644 src/main/webapp/bower_components/jquery/src/manipulation.js delete mode 100644 src/main/webapp/bower_components/jquery/src/manipulation/_evalUrl.js delete mode 100644 src/main/webapp/bower_components/jquery/src/manipulation/support.js delete mode 100644 src/main/webapp/bower_components/jquery/src/manipulation/var/rcheckableType.js delete mode 100644 src/main/webapp/bower_components/jquery/src/offset.js delete mode 100644 src/main/webapp/bower_components/jquery/src/outro.js delete mode 100644 src/main/webapp/bower_components/jquery/src/queue.js delete mode 100644 src/main/webapp/bower_components/jquery/src/queue/delay.js delete mode 100644 src/main/webapp/bower_components/jquery/src/selector-native.js delete mode 100644 src/main/webapp/bower_components/jquery/src/selector-sizzle.js delete mode 100644 src/main/webapp/bower_components/jquery/src/selector.js delete mode 100644 src/main/webapp/bower_components/jquery/src/serialize.js delete mode 100644 src/main/webapp/bower_components/jquery/src/sizzle/dist/sizzle.js delete mode 100644 src/main/webapp/bower_components/jquery/src/sizzle/dist/sizzle.min.js delete mode 100644 src/main/webapp/bower_components/jquery/src/sizzle/dist/sizzle.min.map delete mode 100644 src/main/webapp/bower_components/jquery/src/traversing.js delete mode 100644 src/main/webapp/bower_components/jquery/src/traversing/findFilter.js delete mode 100644 src/main/webapp/bower_components/jquery/src/traversing/var/rneedsContext.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/arr.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/class2type.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/concat.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/hasOwn.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/indexOf.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/pnum.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/push.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/rnotwhite.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/slice.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/strundefined.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/support.js delete mode 100644 src/main/webapp/bower_components/jquery/src/var/toString.js delete mode 100644 src/main/webapp/bower_components/jquery/src/wrap.js delete mode 100644 src/main/webapp/bower_components/json3/.bower.json delete mode 100644 src/main/webapp/bower_components/json3/CHANGELOG.md delete mode 100644 src/main/webapp/bower_components/json3/CONTRIBUTING.md delete mode 100644 src/main/webapp/bower_components/json3/LICENSE delete mode 100644 src/main/webapp/bower_components/json3/README.md delete mode 100644 src/main/webapp/bower_components/json3/bower.json delete mode 100644 src/main/webapp/bower_components/json3/lib/json3.js delete mode 100644 src/main/webapp/bower_components/json3/lib/json3.min.js delete mode 100644 src/main/webapp/scripts/app/fragments/bodyHeader.html create mode 100644 src/main/webapp/scripts/app/fragments/nav.html create mode 100644 src/main/webapp/scripts/app/fragments/welcome.html delete mode 100644 src/main/webapp/scripts/app/main/MainController.js delete mode 100644 src/main/webapp/scripts/app/main/main.html create mode 100644 src/main/webapp/scripts/app/owner-details/owner-details.component.js create mode 100644 src/main/webapp/scripts/app/owner-details/owner-details.template.html create mode 100644 src/main/webapp/scripts/app/owner-form/owner-form.component.js create mode 100644 src/main/webapp/scripts/app/owner-form/owner-form.template.html rename src/main/webapp/scripts/app/{owner => owner-list}/OwnerController.js (99%) create mode 100644 src/main/webapp/scripts/app/owner-list/owner-list.component.js create mode 100644 src/main/webapp/scripts/app/owner-list/owner-list.template.html rename src/main/webapp/scripts/app/{owner => owner-list}/ownerDetail.html (100%) rename src/main/webapp/scripts/app/{owner => owner-list}/ownerForm.html (100%) rename src/main/webapp/scripts/app/{owner => owner-list}/ownerSearchForm.html (100%) delete mode 100644 src/main/webapp/scripts/app/owner/ownerList.html create mode 100644 src/main/webapp/scripts/app/pet-form/pet-form.component.js create mode 100644 src/main/webapp/scripts/app/pet-form/pet-form.template.html create mode 100644 src/main/webapp/scripts/app/vet-list/vet-list.component.js create mode 100644 src/main/webapp/scripts/app/vet-list/vet-list.template.html delete mode 100644 src/main/webapp/scripts/app/vet/VetController.js delete mode 100644 src/main/webapp/scripts/app/vet/vetList.html diff --git a/pom.xml b/pom.xml index adb519718..e83834787 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,18 @@ provided + + org.webjars + bootstrap + 3.3.7 + + + + org.webjars + jquery + 3.1.0 + + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java index 841d0bcd8..4e0c7c4af 100644 --- a/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java +++ b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java @@ -18,6 +18,7 @@ package org.springframework.samples.petclinic.repository; import java.util.Collection; import org.springframework.dao.DataAccessException; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; import org.springframework.data.repository.query.Param; @@ -33,31 +34,4 @@ import org.springframework.samples.petclinic.model.Owner; * @author Sam Brannen * @author Michael Isvy */ -public interface OwnerRepository extends Repository { - - /** - * Retrieve {@link Owner}s from the data store by last name, returning all owners - * whose last name starts with the given name. - * @param lastName Value to search for - * @return a Collection of matching {@link Owner}s (or an empty Collection if none - * found) - */ - @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%") - Collection findByLastName(@Param("lastName") String lastName); - - /** - * Retrieve an {@link Owner} from the data store by id. - * @param id the id to search for - * @return the {@link Owner} if found - */ - @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") - Owner findById(@Param("id") int id); - - /** - * Save an {@link Owner} to the data store, either inserting or updating it. - * @param owner the {@link Owner} to save - */ - void save(Owner owner); - - -} +public interface OwnerRepository extends JpaRepository { } diff --git a/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java b/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java index 936582129..d35e26bdf 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java +++ b/src/main/java/org/springframework/samples/petclinic/service/ClinicService.java @@ -17,7 +17,6 @@ package org.springframework.samples.petclinic.service; import java.util.Collection; -import org.springframework.dao.DataAccessException; import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; @@ -32,20 +31,20 @@ import org.springframework.samples.petclinic.model.Visit; */ public interface ClinicService { - Collection findPetTypes() throws DataAccessException; + Collection findPetTypes(); - Owner findOwnerById(int id) throws DataAccessException; + Owner findOwnerById(int id); - Pet findPetById(int id) throws DataAccessException; + Pet findPetById(int id); - void savePet(Pet pet) throws DataAccessException; + void savePet(Pet pet); - void saveVisit(Visit visit) throws DataAccessException; + void saveVisit(Visit visit); - Collection findVets() throws DataAccessException; + Collection findVets(); - void saveOwner(Owner owner) throws DataAccessException; + void saveOwner(Owner owner); - Collection findOwnerByLastName(String lastName) throws DataAccessException; + Collection findAll(); } diff --git a/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java b/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java index 0d7ff4d0c..59b764092 100644 --- a/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java +++ b/src/main/java/org/springframework/samples/petclinic/service/ClinicServiceImpl.java @@ -63,13 +63,12 @@ public class ClinicServiceImpl implements ClinicService { @Override @Transactional(readOnly = true) public Owner findOwnerById(int id) throws DataAccessException { - return ownerRepository.findById(id); + return ownerRepository.findOne(id); } - @Override @Transactional(readOnly = true) - public Collection findOwnerByLastName(String lastName) throws DataAccessException { - return ownerRepository.findByLastName(lastName); + public Collection findAll() throws DataAccessException { + return ownerRepository.findAll(); } @Override diff --git a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java index 073cf80a9..2c3a1d8d0 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java +++ b/src/main/java/org/springframework/samples/petclinic/web/OwnerResource.java @@ -22,12 +22,12 @@ import org.springframework.http.HttpStatus; import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.service.ClinicService; import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -79,20 +79,9 @@ public class OwnerResource { /** * Read List of Owners */ - @RequestMapping(value = "/owner/list", method = RequestMethod.GET) - public Collection findOwnerCollection(@RequestParam("lastName") String ownerLastName) { - - if (ownerLastName == null) { - ownerLastName = ""; - } - - Collection results = this.clinicService.findOwnerByLastName(ownerLastName); - if (results.isEmpty()) { - return null; - } - else { - return results; - } + @GetMapping("/owner/list") + public Collection findAll() { + return clinicService.findAll(); } /** diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetResource.java b/src/main/java/org/springframework/samples/petclinic/web/PetResource.java index c96b3571b..8a93d3384 100644 --- a/src/main/java/org/springframework/samples/petclinic/web/PetResource.java +++ b/src/main/java/org/springframework/samples/petclinic/web/PetResource.java @@ -15,27 +15,27 @@ */ package org.springframework.samples.petclinic.web; -import java.util.Date; -import java.util.Map; - +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; import lombok.Getter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.HttpStatus; import org.springframework.samples.petclinic.model.Owner; import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.service.ClinicService; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.support.SessionStatus; + +import javax.validation.constraints.Size; +import java.util.Date; +import java.util.Map; /** * @author Juergen Hoeller @@ -52,11 +52,6 @@ public class PetResource { this.clinicService = clinicService; } - @InitBinder - public void setAllowedFields(WebDataBinder dataBinder) { - dataBinder.setDisallowedFields("id"); - } - @GetMapping("/petTypes") Object getPetTypes() { return clinicService.findPetTypes(); @@ -71,16 +66,37 @@ public class PetResource { return "pets/createOrUpdatePetForm"; } - @PostMapping("/owners/{ownerId}/pets/new") - public String processCreationForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) { - new PetValidator().validate(pet, result); - if (result.hasErrors()) { - return "pets/createOrUpdatePetForm"; - } else { - this.clinicService.savePet(pet); - status.setComplete(); - return "redirect:/owner/{ownerId}"; + @PostMapping("/owners/{ownerId}/pets") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void processCreationForm( + @RequestBody PetRequest petRequest, + @PathVariable("ownerId") int ownerId) { + + Pet pet = new Pet(); + Owner owner = this.clinicService.findOwnerById(ownerId); + owner.addPet(pet); + + save(pet, petRequest); + } + + @PutMapping("/owners/{ownerId}/pets/{petId}") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void processUpdateForm(@RequestBody PetRequest petRequest) { + save(clinicService.findPetById(petRequest.getId()), petRequest); + } + + private void save(Pet pet, PetRequest petRequest) { + + pet.setName(petRequest.getName()); + pet.setBirthDate(petRequest.getBirthDate()); + + for (PetType petType : clinicService.findPetTypes()) { + if (petType.getId() == petRequest.getTypeId()) { + pet.setType(petType); + } } + + clinicService.savePet(pet); } @GetMapping("/owner/*/pet/{petId}") @@ -89,17 +105,14 @@ public class PetResource { return new PetDetails(pet); } - @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/edit", method = {RequestMethod.PUT, RequestMethod.POST}) - public String processUpdateForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) { - // we're not using @Valid annotation here because it is easier to define such validation rule in Java - new PetValidator().validate(pet, result); - if (result.hasErrors()) { - return "pets/createOrUpdatePetForm"; - } else { - this.clinicService.savePet(pet); - status.setComplete(); - return "redirect:/owners/{ownerId}"; - } + @Data + static class PetRequest { + int id; + @JsonFormat(pattern = "yyyy-MM-dd") + Date birthDate; + @Size(min = 1) + String name; + int typeId; } @Getter diff --git a/src/main/webapp/WEB-INF/jsp/pets/createOrUpdateVisitForm.jsp b/src/main/webapp/WEB-INF/jsp/pets/createOrUpdateVisitForm.jsp deleted file mode 100644 index 85408dfe1..000000000 --- a/src/main/webapp/WEB-INF/jsp/pets/createOrUpdateVisitForm.jsp +++ /dev/null @@ -1,73 +0,0 @@ - - -<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> -<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> -<%@ taglib prefix="joda" uri="http://www.joda.org/joda/time/tags" %> -<%@ taglib prefix="petclinic" tagdir="/WEB-INF/tags" %> - - - - - - - - -
-

New Visit

- - Pet - - - - - - - - - - - - - - - -
NameBirth DateTypeOwner
- - - - - - -
- - -
-
- -
- Previous Visits - - - - - - - - - - - - - -
DateDescription
- -
- - - diff --git a/src/main/webapp/WEB-INF/no-spring-config-files-there.txt b/src/main/webapp/WEB-INF/no-spring-config-files-there.txt deleted file mode 100644 index 45fb7bf0a..000000000 --- a/src/main/webapp/WEB-INF/no-spring-config-files-there.txt +++ /dev/null @@ -1,4 +0,0 @@ -All Spring config files (including Spring MVC ones) are inside src/main/resource. -There are mostly 2 reasons to that: -- All Spring config files are grouped into one single place -- It is simpler to reference them from inside JUnit tests \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/tags/inputField.tag b/src/main/webapp/WEB-INF/tags/inputField.tag deleted file mode 100644 index 796dc91c0..000000000 --- a/src/main/webapp/WEB-INF/tags/inputField.tag +++ /dev/null @@ -1,19 +0,0 @@ -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> -<%@ attribute name="name" required="true" rtexprvalue="true" - description="Name of corresponding property in bean object" %> -<%@ attribute name="label" required="true" rtexprvalue="true" - description="Label appears in red color if input is considered as invalid after submission" %> - - - -
- - -
- - ${status.errorMessage} -
-
-
\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/tags/selectField.tag b/src/main/webapp/WEB-INF/tags/selectField.tag deleted file mode 100644 index f93256ac8..000000000 --- a/src/main/webapp/WEB-INF/tags/selectField.tag +++ /dev/null @@ -1,23 +0,0 @@ -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> -<%@ attribute name="name" required="true" rtexprvalue="true" - description="Name of corresponding property in bean object" %> -<%@ attribute name="label" required="true" rtexprvalue="true" - description="Label appears in red color if input is considered as invalid after submission" %> -<%@ attribute name="names" required="true" rtexprvalue="true" type="java.util.List" - description="Names in the list" %> -<%@ attribute name="size" required="true" rtexprvalue="true" - description="Size of Select" %> - - - -
- - -
- - ${status.errorMessage} -
-
-
\ No newline at end of file diff --git a/src/main/webapp/bower_components/angular-mocks/.bower.json b/src/main/webapp/bower_components/angular-mocks/.bower.json deleted file mode 100644 index c2d3a35ac..000000000 --- a/src/main/webapp/bower_components/angular-mocks/.bower.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "angular-mocks", - "version": "1.3.11", - "main": "./angular-mocks.js", - "ignore": [], - "dependencies": { - "angular": "1.3.11" - }, - "homepage": "https://github.com/angular/bower-angular-mocks", - "_release": "1.3.11", - "_resolution": { - "type": "version", - "tag": "v1.3.11", - "commit": "2457be05bbe0d16947e2a1a0add1798cbadd11d2" - }, - "_source": "git://github.com/angular/bower-angular-mocks.git", - "_target": "1.3.11", - "_originalSource": "angular-mocks" -} \ No newline at end of file diff --git a/src/main/webapp/bower_components/angular-mocks/README.md b/src/main/webapp/bower_components/angular-mocks/README.md deleted file mode 100644 index 1604ef880..000000000 --- a/src/main/webapp/bower_components/angular-mocks/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# packaged angular-mocks - -This repo is for distribution on `npm` and `bower`. The source for this module is in the -[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngMock). -Please file issues and pull requests against that repo. - -## Install - -You can install this package either with `npm` or with `bower`. - -### npm - -```shell -npm install angular-mocks -``` - -The mocks are then available at `node_modules/angular-mocks/angular-mocks.js`. - -Note that this package is not in CommonJS format, so doing `require('angular-mocks')` will -return `undefined`. - -### bower - -```shell -bower install angular-mocks -``` - -The mocks are then available at `bower_components/angular-mocks/angular-mocks.js`. - -## Documentation - -Documentation is available on the -[AngularJS docs site](https://docs.angularjs.org/guide/unit-testing). - -## License - -The MIT License - -Copyright (c) 2010-2012 Google, Inc. http://angularjs.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/src/main/webapp/bower_components/angular-mocks/angular-mocks.js b/src/main/webapp/bower_components/angular-mocks/angular-mocks.js deleted file mode 100644 index 2a411cc38..000000000 --- a/src/main/webapp/bower_components/angular-mocks/angular-mocks.js +++ /dev/null @@ -1,2382 +0,0 @@ -/** - * @license AngularJS v1.3.11 - * (c) 2010-2014 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular, undefined) { - -'use strict'; - -/** - * @ngdoc object - * @name angular.mock - * @description - * - * Namespace from 'angular-mocks.js' which contains testing related code. - */ -angular.mock = {}; - -/** - * ! This is a private undocumented service ! - * - * @name $browser - * - * @description - * This service is a mock implementation of {@link ng.$browser}. It provides fake - * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr, - * cookies, etc... - * - * The api of this service is the same as that of the real {@link ng.$browser $browser}, except - * that there are several helper methods available which can be used in tests. - */ -angular.mock.$BrowserProvider = function() { - this.$get = function() { - return new angular.mock.$Browser(); - }; -}; - -angular.mock.$Browser = function() { - var self = this; - - this.isMock = true; - self.$$url = "http://server/"; - self.$$lastUrl = self.$$url; // used by url polling fn - self.pollFns = []; - - // TODO(vojta): remove this temporary api - self.$$completeOutstandingRequest = angular.noop; - self.$$incOutstandingRequestCount = angular.noop; - - - // register url polling fn - - self.onUrlChange = function(listener) { - self.pollFns.push( - function() { - if (self.$$lastUrl !== self.$$url || self.$$state !== self.$$lastState) { - self.$$lastUrl = self.$$url; - self.$$lastState = self.$$state; - listener(self.$$url, self.$$state); - } - } - ); - - return listener; - }; - - self.$$checkUrlChange = angular.noop; - - self.cookieHash = {}; - self.lastCookieHash = {}; - self.deferredFns = []; - self.deferredNextId = 0; - - self.defer = function(fn, delay) { - delay = delay || 0; - self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId}); - self.deferredFns.sort(function(a, b) { return a.time - b.time;}); - return self.deferredNextId++; - }; - - - /** - * @name $browser#defer.now - * - * @description - * Current milliseconds mock time. - */ - self.defer.now = 0; - - - self.defer.cancel = function(deferId) { - var fnIndex; - - angular.forEach(self.deferredFns, function(fn, index) { - if (fn.id === deferId) fnIndex = index; - }); - - if (fnIndex !== undefined) { - self.deferredFns.splice(fnIndex, 1); - return true; - } - - return false; - }; - - - /** - * @name $browser#defer.flush - * - * @description - * Flushes all pending requests and executes the defer callbacks. - * - * @param {number=} number of milliseconds to flush. See {@link #defer.now} - */ - self.defer.flush = function(delay) { - if (angular.isDefined(delay)) { - self.defer.now += delay; - } else { - if (self.deferredFns.length) { - self.defer.now = self.deferredFns[self.deferredFns.length - 1].time; - } else { - throw new Error('No deferred tasks to be flushed'); - } - } - - while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) { - self.deferredFns.shift().fn(); - } - }; - - self.$$baseHref = '/'; - self.baseHref = function() { - return this.$$baseHref; - }; -}; -angular.mock.$Browser.prototype = { - -/** - * @name $browser#poll - * - * @description - * run all fns in pollFns - */ - poll: function poll() { - angular.forEach(this.pollFns, function(pollFn) { - pollFn(); - }); - }, - - addPollFn: function(pollFn) { - this.pollFns.push(pollFn); - return pollFn; - }, - - url: function(url, replace, state) { - if (angular.isUndefined(state)) { - state = null; - } - if (url) { - this.$$url = url; - // Native pushState serializes & copies the object; simulate it. - this.$$state = angular.copy(state); - return this; - } - - return this.$$url; - }, - - state: function() { - return this.$$state; - }, - - cookies: function(name, value) { - if (name) { - if (angular.isUndefined(value)) { - delete this.cookieHash[name]; - } else { - if (angular.isString(value) && //strings only - value.length <= 4096) { //strict cookie storage limits - this.cookieHash[name] = value; - } - } - } else { - if (!angular.equals(this.cookieHash, this.lastCookieHash)) { - this.lastCookieHash = angular.copy(this.cookieHash); - this.cookieHash = angular.copy(this.cookieHash); - } - return this.cookieHash; - } - }, - - notifyWhenNoOutstandingRequests: function(fn) { - fn(); - } -}; - - -/** - * @ngdoc provider - * @name $exceptionHandlerProvider - * - * @description - * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors - * passed to the `$exceptionHandler`. - */ - -/** - * @ngdoc service - * @name $exceptionHandler - * - * @description - * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed - * to it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration - * information. - * - * - * ```js - * describe('$exceptionHandlerProvider', function() { - * - * it('should capture log messages and exceptions', function() { - * - * module(function($exceptionHandlerProvider) { - * $exceptionHandlerProvider.mode('log'); - * }); - * - * inject(function($log, $exceptionHandler, $timeout) { - * $timeout(function() { $log.log(1); }); - * $timeout(function() { $log.log(2); throw 'banana peel'; }); - * $timeout(function() { $log.log(3); }); - * expect($exceptionHandler.errors).toEqual([]); - * expect($log.assertEmpty()); - * $timeout.flush(); - * expect($exceptionHandler.errors).toEqual(['banana peel']); - * expect($log.log.logs).toEqual([[1], [2], [3]]); - * }); - * }); - * }); - * ``` - */ - -angular.mock.$ExceptionHandlerProvider = function() { - var handler; - - /** - * @ngdoc method - * @name $exceptionHandlerProvider#mode - * - * @description - * Sets the logging mode. - * - * @param {string} mode Mode of operation, defaults to `rethrow`. - * - * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` - * mode stores an array of errors in `$exceptionHandler.errors`, to allow later - * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and - * {@link ngMock.$log#reset reset()} - * - `rethrow`: If any errors are passed to the handler in tests, it typically means that there - * is a bug in the application or test, so this mock will make these tests fail. - * For any implementations that expect exceptions to be thrown, the `rethrow` mode - * will also maintain a log of thrown errors. - */ - this.mode = function(mode) { - - switch (mode) { - case 'log': - case 'rethrow': - var errors = []; - handler = function(e) { - if (arguments.length == 1) { - errors.push(e); - } else { - errors.push([].slice.call(arguments, 0)); - } - if (mode === "rethrow") { - throw e; - } - }; - handler.errors = errors; - break; - default: - throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!"); - } - }; - - this.$get = function() { - return handler; - }; - - this.mode('rethrow'); -}; - - -/** - * @ngdoc service - * @name $log - * - * @description - * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays - * (one array per logging level). These arrays are exposed as `logs` property of each of the - * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`. - * - */ -angular.mock.$LogProvider = function() { - var debug = true; - - function concat(array1, array2, index) { - return array1.concat(Array.prototype.slice.call(array2, index)); - } - - this.debugEnabled = function(flag) { - if (angular.isDefined(flag)) { - debug = flag; - return this; - } else { - return debug; - } - }; - - this.$get = function() { - var $log = { - log: function() { $log.log.logs.push(concat([], arguments, 0)); }, - warn: function() { $log.warn.logs.push(concat([], arguments, 0)); }, - info: function() { $log.info.logs.push(concat([], arguments, 0)); }, - error: function() { $log.error.logs.push(concat([], arguments, 0)); }, - debug: function() { - if (debug) { - $log.debug.logs.push(concat([], arguments, 0)); - } - } - }; - - /** - * @ngdoc method - * @name $log#reset - * - * @description - * Reset all of the logging arrays to empty. - */ - $log.reset = function() { - /** - * @ngdoc property - * @name $log#log.logs - * - * @description - * Array of messages logged using {@link ng.$log#log `log()`}. - * - * @example - * ```js - * $log.log('Some Log'); - * var first = $log.log.logs.unshift(); - * ``` - */ - $log.log.logs = []; - /** - * @ngdoc property - * @name $log#info.logs - * - * @description - * Array of messages logged using {@link ng.$log#info `info()`}. - * - * @example - * ```js - * $log.info('Some Info'); - * var first = $log.info.logs.unshift(); - * ``` - */ - $log.info.logs = []; - /** - * @ngdoc property - * @name $log#warn.logs - * - * @description - * Array of messages logged using {@link ng.$log#warn `warn()`}. - * - * @example - * ```js - * $log.warn('Some Warning'); - * var first = $log.warn.logs.unshift(); - * ``` - */ - $log.warn.logs = []; - /** - * @ngdoc property - * @name $log#error.logs - * - * @description - * Array of messages logged using {@link ng.$log#error `error()`}. - * - * @example - * ```js - * $log.error('Some Error'); - * var first = $log.error.logs.unshift(); - * ``` - */ - $log.error.logs = []; - /** - * @ngdoc property - * @name $log#debug.logs - * - * @description - * Array of messages logged using {@link ng.$log#debug `debug()`}. - * - * @example - * ```js - * $log.debug('Some Error'); - * var first = $log.debug.logs.unshift(); - * ``` - */ - $log.debug.logs = []; - }; - - /** - * @ngdoc method - * @name $log#assertEmpty - * - * @description - * Assert that all of the logging methods have no logged messages. If any messages are present, - * an exception is thrown. - */ - $log.assertEmpty = function() { - var errors = []; - angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) { - angular.forEach($log[logLevel].logs, function(log) { - angular.forEach(log, function(logItem) { - errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' + - (logItem.stack || '')); - }); - }); - }); - if (errors.length) { - errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or " + - "an expected log message was not checked and removed:"); - errors.push(''); - throw new Error(errors.join('\n---------\n')); - } - }; - - $log.reset(); - return $log; - }; -}; - - -/** - * @ngdoc service - * @name $interval - * - * @description - * Mock implementation of the $interval service. - * - * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to - * move forward by `millis` milliseconds and trigger any functions scheduled to run in that - * time. - * - * @param {function()} fn A function that should be called repeatedly. - * @param {number} delay Number of milliseconds between each function call. - * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat - * indefinitely. - * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise - * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. - * @returns {promise} A promise which will be notified on each iteration. - */ -angular.mock.$IntervalProvider = function() { - this.$get = ['$browser', '$rootScope', '$q', '$$q', - function($browser, $rootScope, $q, $$q) { - var repeatFns = [], - nextRepeatId = 0, - now = 0; - - var $interval = function(fn, delay, count, invokeApply) { - var iteration = 0, - skipApply = (angular.isDefined(invokeApply) && !invokeApply), - deferred = (skipApply ? $$q : $q).defer(), - promise = deferred.promise; - - count = (angular.isDefined(count)) ? count : 0; - promise.then(null, null, fn); - - promise.$$intervalId = nextRepeatId; - - function tick() { - deferred.notify(iteration++); - - if (count > 0 && iteration >= count) { - var fnIndex; - deferred.resolve(iteration); - - angular.forEach(repeatFns, function(fn, index) { - if (fn.id === promise.$$intervalId) fnIndex = index; - }); - - if (fnIndex !== undefined) { - repeatFns.splice(fnIndex, 1); - } - } - - if (skipApply) { - $browser.defer.flush(); - } else { - $rootScope.$apply(); - } - } - - repeatFns.push({ - nextTime:(now + delay), - delay: delay, - fn: tick, - id: nextRepeatId, - deferred: deferred - }); - repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;}); - - nextRepeatId++; - return promise; - }; - /** - * @ngdoc method - * @name $interval#cancel - * - * @description - * Cancels a task associated with the `promise`. - * - * @param {promise} promise A promise from calling the `$interval` function. - * @returns {boolean} Returns `true` if the task was successfully cancelled. - */ - $interval.cancel = function(promise) { - if (!promise) return false; - var fnIndex; - - angular.forEach(repeatFns, function(fn, index) { - if (fn.id === promise.$$intervalId) fnIndex = index; - }); - - if (fnIndex !== undefined) { - repeatFns[fnIndex].deferred.reject('canceled'); - repeatFns.splice(fnIndex, 1); - return true; - } - - return false; - }; - - /** - * @ngdoc method - * @name $interval#flush - * @description - * - * Runs interval tasks scheduled to be run in the next `millis` milliseconds. - * - * @param {number=} millis maximum timeout amount to flush up until. - * - * @return {number} The amount of time moved forward. - */ - $interval.flush = function(millis) { - now += millis; - while (repeatFns.length && repeatFns[0].nextTime <= now) { - var task = repeatFns[0]; - task.fn(); - task.nextTime += task.delay; - repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;}); - } - return millis; - }; - - return $interval; - }]; -}; - - -/* jshint -W101 */ -/* The R_ISO8061_STR regex is never going to fit into the 100 char limit! - * This directive should go inside the anonymous function but a bug in JSHint means that it would - * not be enacted early enough to prevent the warning. - */ -var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; - -function jsonStringToDate(string) { - var match; - if (match = string.match(R_ISO8061_STR)) { - var date = new Date(0), - tzHour = 0, - tzMin = 0; - if (match[9]) { - tzHour = int(match[9] + match[10]); - tzMin = int(match[9] + match[11]); - } - date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3])); - date.setUTCHours(int(match[4] || 0) - tzHour, - int(match[5] || 0) - tzMin, - int(match[6] || 0), - int(match[7] || 0)); - return date; - } - return string; -} - -function int(str) { - return parseInt(str, 10); -} - -function padNumber(num, digits, trim) { - var neg = ''; - if (num < 0) { - neg = '-'; - num = -num; - } - num = '' + num; - while (num.length < digits) num = '0' + num; - if (trim) - num = num.substr(num.length - digits); - return neg + num; -} - - -/** - * @ngdoc type - * @name angular.mock.TzDate - * @description - * - * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`. - * - * Mock of the Date type which has its timezone specified via constructor arg. - * - * The main purpose is to create Date-like instances with timezone fixed to the specified timezone - * offset, so that we can test code that depends on local timezone settings without dependency on - * the time zone settings of the machine where the code is running. - * - * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored) - * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC* - * - * @example - * !!!! WARNING !!!!! - * This is not a complete Date object so only methods that were implemented can be called safely. - * To make matters worse, TzDate instances inherit stuff from Date via a prototype. - * - * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is - * incomplete we might be missing some non-standard methods. This can result in errors like: - * "Date.prototype.foo called on incompatible Object". - * - * ```js - * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z'); - * newYearInBratislava.getTimezoneOffset() => -60; - * newYearInBratislava.getFullYear() => 2010; - * newYearInBratislava.getMonth() => 0; - * newYearInBratislava.getDate() => 1; - * newYearInBratislava.getHours() => 0; - * newYearInBratislava.getMinutes() => 0; - * newYearInBratislava.getSeconds() => 0; - * ``` - * - */ -angular.mock.TzDate = function(offset, timestamp) { - var self = new Date(0); - if (angular.isString(timestamp)) { - var tsStr = timestamp; - - self.origDate = jsonStringToDate(timestamp); - - timestamp = self.origDate.getTime(); - if (isNaN(timestamp)) - throw { - name: "Illegal Argument", - message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string" - }; - } else { - self.origDate = new Date(timestamp); - } - - var localOffset = new Date(timestamp).getTimezoneOffset(); - self.offsetDiff = localOffset * 60 * 1000 - offset * 1000 * 60 * 60; - self.date = new Date(timestamp + self.offsetDiff); - - self.getTime = function() { - return self.date.getTime() - self.offsetDiff; - }; - - self.toLocaleDateString = function() { - return self.date.toLocaleDateString(); - }; - - self.getFullYear = function() { - return self.date.getFullYear(); - }; - - self.getMonth = function() { - return self.date.getMonth(); - }; - - self.getDate = function() { - return self.date.getDate(); - }; - - self.getHours = function() { - return self.date.getHours(); - }; - - self.getMinutes = function() { - return self.date.getMinutes(); - }; - - self.getSeconds = function() { - return self.date.getSeconds(); - }; - - self.getMilliseconds = function() { - return self.date.getMilliseconds(); - }; - - self.getTimezoneOffset = function() { - return offset * 60; - }; - - self.getUTCFullYear = function() { - return self.origDate.getUTCFullYear(); - }; - - self.getUTCMonth = function() { - return self.origDate.getUTCMonth(); - }; - - self.getUTCDate = function() { - return self.origDate.getUTCDate(); - }; - - self.getUTCHours = function() { - return self.origDate.getUTCHours(); - }; - - self.getUTCMinutes = function() { - return self.origDate.getUTCMinutes(); - }; - - self.getUTCSeconds = function() { - return self.origDate.getUTCSeconds(); - }; - - self.getUTCMilliseconds = function() { - return self.origDate.getUTCMilliseconds(); - }; - - self.getDay = function() { - return self.date.getDay(); - }; - - // provide this method only on browsers that already have it - if (self.toISOString) { - self.toISOString = function() { - return padNumber(self.origDate.getUTCFullYear(), 4) + '-' + - padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' + - padNumber(self.origDate.getUTCDate(), 2) + 'T' + - padNumber(self.origDate.getUTCHours(), 2) + ':' + - padNumber(self.origDate.getUTCMinutes(), 2) + ':' + - padNumber(self.origDate.getUTCSeconds(), 2) + '.' + - padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'; - }; - } - - //hide all methods not implemented in this mock that the Date prototype exposes - var unimplementedMethods = ['getUTCDay', - 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', - 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', - 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', - 'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString', - 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf']; - - angular.forEach(unimplementedMethods, function(methodName) { - self[methodName] = function() { - throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock"); - }; - }); - - return self; -}; - -//make "tzDateInstance instanceof Date" return true -angular.mock.TzDate.prototype = Date.prototype; -/* jshint +W101 */ - -angular.mock.animate = angular.module('ngAnimateMock', ['ng']) - - .config(['$provide', function($provide) { - - var reflowQueue = []; - $provide.value('$$animateReflow', function(fn) { - var index = reflowQueue.length; - reflowQueue.push(fn); - return function cancel() { - reflowQueue.splice(index, 1); - }; - }); - - $provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser', - function($delegate, $$asyncCallback, $timeout, $browser) { - var animate = { - queue: [], - cancel: $delegate.cancel, - enabled: $delegate.enabled, - triggerCallbackEvents: function() { - $$asyncCallback.flush(); - }, - triggerCallbackPromise: function() { - $timeout.flush(0); - }, - triggerCallbacks: function() { - this.triggerCallbackEvents(); - this.triggerCallbackPromise(); - }, - triggerReflow: function() { - angular.forEach(reflowQueue, function(fn) { - fn(); - }); - reflowQueue = []; - } - }; - - angular.forEach( - ['animate','enter','leave','move','addClass','removeClass','setClass'], function(method) { - animate[method] = function() { - animate.queue.push({ - event: method, - element: arguments[0], - options: arguments[arguments.length - 1], - args: arguments - }); - return $delegate[method].apply($delegate, arguments); - }; - }); - - return animate; - }]); - - }]); - - -/** - * @ngdoc function - * @name angular.mock.dump - * @description - * - * *NOTE*: this is not an injectable instance, just a globally available function. - * - * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for - * debugging. - * - * This method is also available on window, where it can be used to display objects on debug - * console. - * - * @param {*} object - any object to turn into string. - * @return {string} a serialized string of the argument - */ -angular.mock.dump = function(object) { - return serialize(object); - - function serialize(object) { - var out; - - if (angular.isElement(object)) { - object = angular.element(object); - out = angular.element('
'); - angular.forEach(object, function(element) { - out.append(angular.element(element).clone()); - }); - out = out.html(); - } else if (angular.isArray(object)) { - out = []; - angular.forEach(object, function(o) { - out.push(serialize(o)); - }); - out = '[ ' + out.join(', ') + ' ]'; - } else if (angular.isObject(object)) { - if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) { - out = serializeScope(object); - } else if (object instanceof Error) { - out = object.stack || ('' + object.name + ': ' + object.message); - } else { - // TODO(i): this prevents methods being logged, - // we should have a better way to serialize objects - out = angular.toJson(object, true); - } - } else { - out = String(object); - } - - return out; - } - - function serializeScope(scope, offset) { - offset = offset || ' '; - var log = [offset + 'Scope(' + scope.$id + '): {']; - for (var key in scope) { - if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) { - log.push(' ' + key + ': ' + angular.toJson(scope[key])); - } - } - var child = scope.$$childHead; - while (child) { - log.push(serializeScope(child, offset + ' ')); - child = child.$$nextSibling; - } - log.push('}'); - return log.join('\n' + offset); - } -}; - -/** - * @ngdoc service - * @name $httpBackend - * @description - * Fake HTTP backend implementation suitable for unit testing applications that use the - * {@link ng.$http $http service}. - * - * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less - * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}. - * - * During unit testing, we want our unit tests to run quickly and have no external dependencies so - * we don’t want to send [XHR](https://developer.mozilla.org/en/xmlhttprequest) or - * [JSONP](http://en.wikipedia.org/wiki/JSONP) requests to a real server. All we really need is - * to verify whether a certain request has been sent or not, or alternatively just let the - * application make requests, respond with pre-trained responses and assert that the end result is - * what we expect it to be. - * - * This mock implementation can be used to respond with static or dynamic responses via the - * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc). - * - * When an Angular application needs some data from a server, it calls the $http service, which - * sends the request to a real server using $httpBackend service. With dependency injection, it is - * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify - * the requests and respond with some testing data without sending a request to a real server. - * - * There are two ways to specify what test data should be returned as http responses by the mock - * backend when the code under test makes http requests: - * - * - `$httpBackend.expect` - specifies a request expectation - * - `$httpBackend.when` - specifies a backend definition - * - * - * # Request Expectations vs Backend Definitions - * - * Request expectations provide a way to make assertions about requests made by the application and - * to define responses for those requests. The test will fail if the expected requests are not made - * or they are made in the wrong order. - * - * Backend definitions allow you to define a fake backend for your application which doesn't assert - * if a particular request was made or not, it just returns a trained response if a request is made. - * The test will pass whether or not the request gets made during testing. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Request expectationsBackend definitions
Syntax.expect(...).respond(...).when(...).respond(...)
Typical usagestrict unit testsloose (black-box) unit testing
Fulfills multiple requestsNOYES
Order of requests mattersYESNO
Request requiredYESNO
Response requiredoptional (see below)YES
- * - * In cases where both backend definitions and request expectations are specified during unit - * testing, the request expectations are evaluated first. - * - * If a request expectation has no response specified, the algorithm will search your backend - * definitions for an appropriate response. - * - * If a request didn't match any expectation or if the expectation doesn't have the response - * defined, the backend definitions are evaluated in sequential order to see if any of them match - * the request. The response from the first matched definition is returned. - * - * - * # Flushing HTTP requests - * - * The $httpBackend used in production always responds to requests asynchronously. If we preserved - * this behavior in unit testing, we'd have to create async unit tests, which are hard to write, - * to follow and to maintain. But neither can the testing mock respond synchronously; that would - * change the execution of the code under test. For this reason, the mock $httpBackend has a - * `flush()` method, which allows the test to explicitly flush pending requests. This preserves - * the async api of the backend, while allowing the test to execute synchronously. - * - * - * # Unit testing with mock $httpBackend - * The following code shows how to setup and use the mock backend when unit testing a controller. - * First we create the controller under test: - * - ```js - // The module code - angular - .module('MyApp', []) - .controller('MyController', MyController); - - // The controller code - function MyController($scope, $http) { - var authToken; - - $http.get('/auth.py').success(function(data, status, headers) { - authToken = headers('A-Token'); - $scope.user = data; - }); - - $scope.saveMessage = function(message) { - var headers = { 'Authorization': authToken }; - $scope.status = 'Saving...'; - - $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) { - $scope.status = ''; - }).error(function() { - $scope.status = 'ERROR!'; - }); - }; - } - ``` - * - * Now we setup the mock backend and create the test specs: - * - ```js - // testing controller - describe('MyController', function() { - var $httpBackend, $rootScope, createController, authRequestHandler; - - // Set up the module - beforeEach(module('MyApp')); - - beforeEach(inject(function($injector) { - // Set up the mock http service responses - $httpBackend = $injector.get('$httpBackend'); - // backend definition common for all tests - authRequestHandler = $httpBackend.when('GET', '/auth.py') - .respond({userId: 'userX'}, {'A-Token': 'xxx'}); - - // Get hold of a scope (i.e. the root scope) - $rootScope = $injector.get('$rootScope'); - // The $controller service is used to create instances of controllers - var $controller = $injector.get('$controller'); - - createController = function() { - return $controller('MyController', {'$scope' : $rootScope }); - }; - })); - - - afterEach(function() { - $httpBackend.verifyNoOutstandingExpectation(); - $httpBackend.verifyNoOutstandingRequest(); - }); - - - it('should fetch authentication token', function() { - $httpBackend.expectGET('/auth.py'); - var controller = createController(); - $httpBackend.flush(); - }); - - - it('should fail authentication', function() { - - // Notice how you can change the response even after it was set - authRequestHandler.respond(401, ''); - - $httpBackend.expectGET('/auth.py'); - var controller = createController(); - $httpBackend.flush(); - expect($rootScope.status).toBe('Failed...'); - }); - - - it('should send msg to server', function() { - var controller = createController(); - $httpBackend.flush(); - - // now you don’t care about the authentication, but - // the controller will still send the request and - // $httpBackend will respond without you having to - // specify the expectation and response for this request - - $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, ''); - $rootScope.saveMessage('message content'); - expect($rootScope.status).toBe('Saving...'); - $httpBackend.flush(); - expect($rootScope.status).toBe(''); - }); - - - it('should send auth header', function() { - var controller = createController(); - $httpBackend.flush(); - - $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) { - // check if the header was send, if it wasn't the expectation won't - // match the request and the test will fail - return headers['Authorization'] == 'xxx'; - }).respond(201, ''); - - $rootScope.saveMessage('whatever'); - $httpBackend.flush(); - }); - }); - ``` - */ -angular.mock.$HttpBackendProvider = function() { - this.$get = ['$rootScope', '$timeout', createHttpBackendMock]; -}; - -/** - * General factory function for $httpBackend mock. - * Returns instance for unit testing (when no arguments specified): - * - passing through is disabled - * - auto flushing is disabled - * - * Returns instance for e2e testing (when `$delegate` and `$browser` specified): - * - passing through (delegating request to real backend) is enabled - * - auto flushing is enabled - * - * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified) - * @param {Object=} $browser Auto-flushing enabled if specified - * @return {Object} Instance of $httpBackend mock - */ -function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { - var definitions = [], - expectations = [], - responses = [], - responsesPush = angular.bind(responses, responses.push), - copy = angular.copy; - - function createResponse(status, data, headers, statusText) { - if (angular.isFunction(status)) return status; - - return function() { - return angular.isNumber(status) - ? [status, data, headers, statusText] - : [200, status, data, headers]; - }; - } - - // TODO(vojta): change params to: method, url, data, headers, callback - function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) { - var xhr = new MockXhr(), - expectation = expectations[0], - wasExpected = false; - - function prettyPrint(data) { - return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp) - ? data - : angular.toJson(data); - } - - function wrapResponse(wrapped) { - if (!$browser && timeout) { - timeout.then ? timeout.then(handleTimeout) : $timeout(handleTimeout, timeout); - } - - return handleResponse; - - function handleResponse() { - var response = wrapped.response(method, url, data, headers); - xhr.$$respHeaders = response[2]; - callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(), - copy(response[3] || '')); - } - - function handleTimeout() { - for (var i = 0, ii = responses.length; i < ii; i++) { - if (responses[i] === handleResponse) { - responses.splice(i, 1); - callback(-1, undefined, ''); - break; - } - } - } - } - - if (expectation && expectation.match(method, url)) { - if (!expectation.matchData(data)) - throw new Error('Expected ' + expectation + ' with different data\n' + - 'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data); - - if (!expectation.matchHeaders(headers)) - throw new Error('Expected ' + expectation + ' with different headers\n' + - 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' + - prettyPrint(headers)); - - expectations.shift(); - - if (expectation.response) { - responses.push(wrapResponse(expectation)); - return; - } - wasExpected = true; - } - - var i = -1, definition; - while ((definition = definitions[++i])) { - if (definition.match(method, url, data, headers || {})) { - if (definition.response) { - // if $browser specified, we do auto flush all requests - ($browser ? $browser.defer : responsesPush)(wrapResponse(definition)); - } else if (definition.passThrough) { - $delegate(method, url, data, callback, headers, timeout, withCredentials); - } else throw new Error('No response defined !'); - return; - } - } - throw wasExpected ? - new Error('No response defined !') : - new Error('Unexpected request: ' + method + ' ' + url + '\n' + - (expectation ? 'Expected ' + expectation : 'No more request expected')); - } - - /** - * @ngdoc method - * @name $httpBackend#when - * @description - * Creates a new backend definition. - * - * @param {string} method HTTP method. - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current definition. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - * - * - respond – - * `{function([status,] data[, headers, statusText]) - * | function(function(method, url, data, headers)}` - * – The respond method takes a set of static data to be returned or a function that can - * return an array containing response status (number), response data (string), response - * headers (Object), and the text for the status (string). The respond method returns the - * `requestHandler` object for possible overrides. - */ - $httpBackend.when = function(method, url, data, headers) { - var definition = new MockHttpExpectation(method, url, data, headers), - chain = { - respond: function(status, data, headers, statusText) { - definition.passThrough = undefined; - definition.response = createResponse(status, data, headers, statusText); - return chain; - } - }; - - if ($browser) { - chain.passThrough = function() { - definition.response = undefined; - definition.passThrough = true; - return chain; - }; - } - - definitions.push(definition); - return chain; - }; - - /** - * @ngdoc method - * @name $httpBackend#whenGET - * @description - * Creates a new backend definition for GET requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenHEAD - * @description - * Creates a new backend definition for HEAD requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenDELETE - * @description - * Creates a new backend definition for DELETE requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenPOST - * @description - * Creates a new backend definition for POST requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenPUT - * @description - * Creates a new backend definition for PUT requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives - * data string and returns true if the data is as expected. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#whenJSONP - * @description - * Creates a new backend definition for JSONP requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - createShortMethods('when'); - - - /** - * @ngdoc method - * @name $httpBackend#expect - * @description - * Creates a new request expectation. - * - * @param {string} method HTTP method. - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current expectation. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - * - * - respond – - * `{function([status,] data[, headers, statusText]) - * | function(function(method, url, data, headers)}` - * – The respond method takes a set of static data to be returned or a function that can - * return an array containing response status (number), response data (string), response - * headers (Object), and the text for the status (string). The respond method returns the - * `requestHandler` object for possible overrides. - */ - $httpBackend.expect = function(method, url, data, headers) { - var expectation = new MockHttpExpectation(method, url, data, headers), - chain = { - respond: function(status, data, headers, statusText) { - expectation.response = createResponse(status, data, headers, statusText); - return chain; - } - }; - - expectations.push(expectation); - return chain; - }; - - - /** - * @ngdoc method - * @name $httpBackend#expectGET - * @description - * Creates a new request expectation for GET requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. See #expect for more info. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectHEAD - * @description - * Creates a new request expectation for HEAD requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectDELETE - * @description - * Creates a new request expectation for DELETE requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectPOST - * @description - * Creates a new request expectation for POST requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectPUT - * @description - * Creates a new request expectation for PUT requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectPATCH - * @description - * Creates a new request expectation for PATCH requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that - * receives data string and returns true if the data is as expected, or Object if request body - * is in JSON format. - * @param {Object=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - - /** - * @ngdoc method - * @name $httpBackend#expectJSONP - * @description - * Creates a new request expectation for JSONP requests. For more info see `expect()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. You can save this object for later use and invoke `respond` again in - * order to change how a matched request is handled. - */ - createShortMethods('expect'); - - - /** - * @ngdoc method - * @name $httpBackend#flush - * @description - * Flushes all pending requests using the trained responses. - * - * @param {number=} count Number of responses to flush (in the order they arrived). If undefined, - * all pending requests will be flushed. If there are no pending requests when the flush method - * is called an exception is thrown (as this typically a sign of programming error). - */ - $httpBackend.flush = function(count, digest) { - if (digest !== false) $rootScope.$digest(); - if (!responses.length) throw new Error('No pending request to flush !'); - - if (angular.isDefined(count) && count !== null) { - while (count--) { - if (!responses.length) throw new Error('No more pending request to flush !'); - responses.shift()(); - } - } else { - while (responses.length) { - responses.shift()(); - } - } - $httpBackend.verifyNoOutstandingExpectation(digest); - }; - - - /** - * @ngdoc method - * @name $httpBackend#verifyNoOutstandingExpectation - * @description - * Verifies that all of the requests defined via the `expect` api were made. If any of the - * requests were not made, verifyNoOutstandingExpectation throws an exception. - * - * Typically, you would call this method following each test case that asserts requests using an - * "afterEach" clause. - * - * ```js - * afterEach($httpBackend.verifyNoOutstandingExpectation); - * ``` - */ - $httpBackend.verifyNoOutstandingExpectation = function(digest) { - if (digest !== false) $rootScope.$digest(); - if (expectations.length) { - throw new Error('Unsatisfied requests: ' + expectations.join(', ')); - } - }; - - - /** - * @ngdoc method - * @name $httpBackend#verifyNoOutstandingRequest - * @description - * Verifies that there are no outstanding requests that need to be flushed. - * - * Typically, you would call this method following each test case that asserts requests using an - * "afterEach" clause. - * - * ```js - * afterEach($httpBackend.verifyNoOutstandingRequest); - * ``` - */ - $httpBackend.verifyNoOutstandingRequest = function() { - if (responses.length) { - throw new Error('Unflushed requests: ' + responses.length); - } - }; - - - /** - * @ngdoc method - * @name $httpBackend#resetExpectations - * @description - * Resets all request expectations, but preserves all backend definitions. Typically, you would - * call resetExpectations during a multiple-phase test when you want to reuse the same instance of - * $httpBackend mock. - */ - $httpBackend.resetExpectations = function() { - expectations.length = 0; - responses.length = 0; - }; - - return $httpBackend; - - - function createShortMethods(prefix) { - angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD'], function(method) { - $httpBackend[prefix + method] = function(url, headers) { - return $httpBackend[prefix](method, url, undefined, headers); - }; - }); - - angular.forEach(['PUT', 'POST', 'PATCH'], function(method) { - $httpBackend[prefix + method] = function(url, data, headers) { - return $httpBackend[prefix](method, url, data, headers); - }; - }); - } -} - -function MockHttpExpectation(method, url, data, headers) { - - this.data = data; - this.headers = headers; - - this.match = function(m, u, d, h) { - if (method != m) return false; - if (!this.matchUrl(u)) return false; - if (angular.isDefined(d) && !this.matchData(d)) return false; - if (angular.isDefined(h) && !this.matchHeaders(h)) return false; - return true; - }; - - this.matchUrl = function(u) { - if (!url) return true; - if (angular.isFunction(url.test)) return url.test(u); - if (angular.isFunction(url)) return url(u); - return url == u; - }; - - this.matchHeaders = function(h) { - if (angular.isUndefined(headers)) return true; - if (angular.isFunction(headers)) return headers(h); - return angular.equals(headers, h); - }; - - this.matchData = function(d) { - if (angular.isUndefined(data)) return true; - if (data && angular.isFunction(data.test)) return data.test(d); - if (data && angular.isFunction(data)) return data(d); - if (data && !angular.isString(data)) { - return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d)); - } - return data == d; - }; - - this.toString = function() { - return method + ' ' + url; - }; -} - -function createMockXhr() { - return new MockXhr(); -} - -function MockXhr() { - - // hack for testing $http, $httpBackend - MockXhr.$$lastInstance = this; - - this.open = function(method, url, async) { - this.$$method = method; - this.$$url = url; - this.$$async = async; - this.$$reqHeaders = {}; - this.$$respHeaders = {}; - }; - - this.send = function(data) { - this.$$data = data; - }; - - this.setRequestHeader = function(key, value) { - this.$$reqHeaders[key] = value; - }; - - this.getResponseHeader = function(name) { - // the lookup must be case insensitive, - // that's why we try two quick lookups first and full scan last - var header = this.$$respHeaders[name]; - if (header) return header; - - name = angular.lowercase(name); - header = this.$$respHeaders[name]; - if (header) return header; - - header = undefined; - angular.forEach(this.$$respHeaders, function(headerVal, headerName) { - if (!header && angular.lowercase(headerName) == name) header = headerVal; - }); - return header; - }; - - this.getAllResponseHeaders = function() { - var lines = []; - - angular.forEach(this.$$respHeaders, function(value, key) { - lines.push(key + ': ' + value); - }); - return lines.join('\n'); - }; - - this.abort = angular.noop; -} - - -/** - * @ngdoc service - * @name $timeout - * @description - * - * This service is just a simple decorator for {@link ng.$timeout $timeout} service - * that adds a "flush" and "verifyNoPendingTasks" methods. - */ - -angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $browser) { - - /** - * @ngdoc method - * @name $timeout#flush - * @description - * - * Flushes the queue of pending tasks. - * - * @param {number=} delay maximum timeout amount to flush up until - */ - $delegate.flush = function(delay) { - $browser.defer.flush(delay); - }; - - /** - * @ngdoc method - * @name $timeout#verifyNoPendingTasks - * @description - * - * Verifies that there are no pending tasks that need to be flushed. - */ - $delegate.verifyNoPendingTasks = function() { - if ($browser.deferredFns.length) { - throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' + - formatPendingTasksAsString($browser.deferredFns)); - } - }; - - function formatPendingTasksAsString(tasks) { - var result = []; - angular.forEach(tasks, function(task) { - result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}'); - }); - - return result.join(', '); - } - - return $delegate; -}]; - -angular.mock.$RAFDecorator = ['$delegate', function($delegate) { - var queue = []; - var rafFn = function(fn) { - var index = queue.length; - queue.push(fn); - return function() { - queue.splice(index, 1); - }; - }; - - rafFn.supported = $delegate.supported; - - rafFn.flush = function() { - if (queue.length === 0) { - throw new Error('No rAF callbacks present'); - } - - var length = queue.length; - for (var i = 0; i < length; i++) { - queue[i](); - } - - queue = []; - }; - - return rafFn; -}]; - -angular.mock.$AsyncCallbackDecorator = ['$delegate', function($delegate) { - var callbacks = []; - var addFn = function(fn) { - callbacks.push(fn); - }; - addFn.flush = function() { - angular.forEach(callbacks, function(fn) { - fn(); - }); - callbacks = []; - }; - return addFn; -}]; - -/** - * - */ -angular.mock.$RootElementProvider = function() { - this.$get = function() { - return angular.element('
'); - }; -}; - -/** - * @ngdoc module - * @name ngMock - * @packageName angular-mocks - * @description - * - * # ngMock - * - * The `ngMock` module provides support to inject and mock Angular services into unit tests. - * In addition, ngMock also extends various core ng services such that they can be - * inspected and controlled in a synchronous manner within test code. - * - * - *
- * - */ -angular.module('ngMock', ['ng']).provider({ - $browser: angular.mock.$BrowserProvider, - $exceptionHandler: angular.mock.$ExceptionHandlerProvider, - $log: angular.mock.$LogProvider, - $interval: angular.mock.$IntervalProvider, - $httpBackend: angular.mock.$HttpBackendProvider, - $rootElement: angular.mock.$RootElementProvider -}).config(['$provide', function($provide) { - $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); - $provide.decorator('$$rAF', angular.mock.$RAFDecorator); - $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator); - $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator); -}]); - -/** - * @ngdoc module - * @name ngMockE2E - * @module ngMockE2E - * @packageName angular-mocks - * @description - * - * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing. - * Currently there is only one mock present in this module - - * the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock. - */ -angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { - $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator); -}]); - -/** - * @ngdoc service - * @name $httpBackend - * @module ngMockE2E - * @description - * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of - * applications that use the {@link ng.$http $http service}. - * - * *Note*: For fake http backend implementation suitable for unit testing please see - * {@link ngMock.$httpBackend unit-testing $httpBackend mock}. - * - * This implementation can be used to respond with static or dynamic responses via the `when` api - * and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the - * real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch - * templates from a webserver). - * - * As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application - * is being developed with the real backend api replaced with a mock, it is often desirable for - * certain category of requests to bypass the mock and issue a real http request (e.g. to fetch - * templates or static files from the webserver). To configure the backend with this behavior - * use the `passThrough` request handler of `when` instead of `respond`. - * - * Additionally, we don't want to manually have to flush mocked out requests like we do during unit - * testing. For this reason the e2e $httpBackend flushes mocked out requests - * automatically, closely simulating the behavior of the XMLHttpRequest object. - * - * To setup the application to run with this http backend, you have to create a module that depends - * on the `ngMockE2E` and your application modules and defines the fake backend: - * - * ```js - * myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']); - * myAppDev.run(function($httpBackend) { - * phones = [{name: 'phone1'}, {name: 'phone2'}]; - * - * // returns the current list of phones - * $httpBackend.whenGET('/phones').respond(phones); - * - * // adds a new phone to the phones array - * $httpBackend.whenPOST('/phones').respond(function(method, url, data) { - * var phone = angular.fromJson(data); - * phones.push(phone); - * return [200, phone, {}]; - * }); - * $httpBackend.whenGET(/^\/templates\//).passThrough(); - * //... - * }); - * ``` - * - * Afterwards, bootstrap your app with this new module. - */ - -/** - * @ngdoc method - * @name $httpBackend#when - * @module ngMockE2E - * @description - * Creates a new backend definition. - * - * @param {string} method HTTP method. - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header - * object and returns true if the headers match the current definition. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - * - * - respond – - * `{function([status,] data[, headers, statusText]) - * | function(function(method, url, data, headers)}` - * – The respond method takes a set of static data to be returned or a function that can return - * an array containing response status (number), response data (string), response headers - * (Object), and the text for the status (string). - * - passThrough – `{function()}` – Any request matching a backend definition with - * `passThrough` handler will be passed through to the real backend (an XHR request will be made - * to the server.) - * - Both methods return the `requestHandler` object for possible overrides. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenGET - * @module ngMockE2E - * @description - * Creates a new backend definition for GET requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenHEAD - * @module ngMockE2E - * @description - * Creates a new backend definition for HEAD requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenDELETE - * @module ngMockE2E - * @description - * Creates a new backend definition for DELETE requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenPOST - * @module ngMockE2E - * @description - * Creates a new backend definition for POST requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenPUT - * @module ngMockE2E - * @description - * Creates a new backend definition for PUT requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenPATCH - * @module ngMockE2E - * @description - * Creates a new backend definition for PATCH requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @param {(string|RegExp)=} data HTTP request body. - * @param {(Object|function(Object))=} headers HTTP headers. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ - -/** - * @ngdoc method - * @name $httpBackend#whenJSONP - * @module ngMockE2E - * @description - * Creates a new backend definition for JSONP requests. For more info see `when()`. - * - * @param {string|RegExp|function(string)} url HTTP url or function that receives the url - * and returns true if the url match the current definition. - * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. You can save this object for later use and invoke - * `respond` or `passThrough` again in order to change how a matched request is handled. - */ -angular.mock.e2e = {}; -angular.mock.e2e.$httpBackendDecorator = - ['$rootScope', '$timeout', '$delegate', '$browser', createHttpBackendMock]; - - -/** - * @ngdoc type - * @name $rootScope.Scope - * @module ngMock - * @description - * {@link ng.$rootScope.Scope Scope} type decorated with helper methods useful for testing. These - * methods are automatically available on any {@link ng.$rootScope.Scope Scope} instance when - * `ngMock` module is loaded. - * - * In addition to all the regular `Scope` methods, the following helper methods are available: - */ -angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) { - - var $rootScopePrototype = Object.getPrototypeOf($delegate); - - $rootScopePrototype.$countChildScopes = countChildScopes; - $rootScopePrototype.$countWatchers = countWatchers; - - return $delegate; - - // ------------------------------------------------------------------------------------------ // - - /** - * @ngdoc method - * @name $rootScope.Scope#$countChildScopes - * @module ngMock - * @description - * Counts all the direct and indirect child scopes of the current scope. - * - * The current scope is excluded from the count. The count includes all isolate child scopes. - * - * @returns {number} Total number of child scopes. - */ - function countChildScopes() { - // jshint validthis: true - var count = 0; // exclude the current scope - var pendingChildHeads = [this.$$childHead]; - var currentScope; - - while (pendingChildHeads.length) { - currentScope = pendingChildHeads.shift(); - - while (currentScope) { - count += 1; - pendingChildHeads.push(currentScope.$$childHead); - currentScope = currentScope.$$nextSibling; - } - } - - return count; - } - - - /** - * @ngdoc method - * @name $rootScope.Scope#$countWatchers - * @module ngMock - * @description - * Counts all the watchers of direct and indirect child scopes of the current scope. - * - * The watchers of the current scope are included in the count and so are all the watchers of - * isolate child scopes. - * - * @returns {number} Total number of watchers. - */ - function countWatchers() { - // jshint validthis: true - var count = this.$$watchers ? this.$$watchers.length : 0; // include the current scope - var pendingChildHeads = [this.$$childHead]; - var currentScope; - - while (pendingChildHeads.length) { - currentScope = pendingChildHeads.shift(); - - while (currentScope) { - count += currentScope.$$watchers ? currentScope.$$watchers.length : 0; - pendingChildHeads.push(currentScope.$$childHead); - currentScope = currentScope.$$nextSibling; - } - } - - return count; - } -}]; - - -if (window.jasmine || window.mocha) { - - var currentSpec = null, - isSpecRunning = function() { - return !!currentSpec; - }; - - - (window.beforeEach || window.setup)(function() { - currentSpec = this; - }); - - (window.afterEach || window.teardown)(function() { - var injector = currentSpec.$injector; - - angular.forEach(currentSpec.$modules, function(module) { - if (module && module.$$hashKey) { - module.$$hashKey = undefined; - } - }); - - currentSpec.$injector = null; - currentSpec.$modules = null; - currentSpec = null; - - if (injector) { - injector.get('$rootElement').off(); - injector.get('$browser').pollFns.length = 0; - } - - // clean up jquery's fragment cache - angular.forEach(angular.element.fragments, function(val, key) { - delete angular.element.fragments[key]; - }); - - MockXhr.$$lastInstance = null; - - angular.forEach(angular.callbacks, function(val, key) { - delete angular.callbacks[key]; - }); - angular.callbacks.counter = 0; - }); - - /** - * @ngdoc function - * @name angular.mock.module - * @description - * - * *NOTE*: This function is also published on window for easy access.
- * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha - * - * This function registers a module configuration code. It collects the configuration information - * which will be used when the injector is created by {@link angular.mock.inject inject}. - * - * See {@link angular.mock.inject inject} for usage example - * - * @param {...(string|Function|Object)} fns any number of modules which are represented as string - * aliases or as anonymous module initialization functions. The modules are used to - * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an - * object literal is passed they will be registered as values in the module, the key being - * the module name and the value being what is returned. - */ - window.module = angular.mock.module = function() { - var moduleFns = Array.prototype.slice.call(arguments, 0); - return isSpecRunning() ? workFn() : workFn; - ///////////////////// - function workFn() { - if (currentSpec.$injector) { - throw new Error('Injector already created, can not register a module!'); - } else { - var modules = currentSpec.$modules || (currentSpec.$modules = []); - angular.forEach(moduleFns, function(module) { - if (angular.isObject(module) && !angular.isArray(module)) { - modules.push(function($provide) { - angular.forEach(module, function(value, key) { - $provide.value(key, value); - }); - }); - } else { - modules.push(module); - } - }); - } - } - }; - - /** - * @ngdoc function - * @name angular.mock.inject - * @description - * - * *NOTE*: This function is also published on window for easy access.
- * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha - * - * The inject function wraps a function into an injectable function. The inject() creates new - * instance of {@link auto.$injector $injector} per test, which is then used for - * resolving references. - * - * - * ## Resolving References (Underscore Wrapping) - * Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this - * in multiple `it()` clauses. To be able to do this we must assign the reference to a variable - * that is declared in the scope of the `describe()` block. Since we would, most likely, want - * the variable to have the same name of the reference we have a problem, since the parameter - * to the `inject()` function would hide the outer variable. - * - * To help with this, the injected parameters can, optionally, be enclosed with underscores. - * These are ignored by the injector when the reference name is resolved. - * - * For example, the parameter `_myService_` would be resolved as the reference `myService`. - * Since it is available in the function body as _myService_, we can then assign it to a variable - * defined in an outer scope. - * - * ``` - * // Defined out reference variable outside - * var myService; - * - * // Wrap the parameter in underscores - * beforeEach( inject( function(_myService_){ - * myService = _myService_; - * })); - * - * // Use myService in a series of tests. - * it('makes use of myService', function() { - * myService.doStuff(); - * }); - * - * ``` - * - * See also {@link angular.mock.module angular.mock.module} - * - * ## Example - * Example of what a typical jasmine tests looks like with the inject method. - * ```js - * - * angular.module('myApplicationModule', []) - * .value('mode', 'app') - * .value('version', 'v1.0.1'); - * - * - * describe('MyApp', function() { - * - * // You need to load modules that you want to test, - * // it loads only the "ng" module by default. - * beforeEach(module('myApplicationModule')); - * - * - * // inject() is used to inject arguments of all given functions - * it('should provide a version', inject(function(mode, version) { - * expect(version).toEqual('v1.0.1'); - * expect(mode).toEqual('app'); - * })); - * - * - * // The inject and module method can also be used inside of the it or beforeEach - * it('should override a version and test the new version is injected', function() { - * // module() takes functions or strings (module aliases) - * module(function($provide) { - * $provide.value('version', 'overridden'); // override version here - * }); - * - * inject(function(version) { - * expect(version).toEqual('overridden'); - * }); - * }); - * }); - * - * ``` - * - * @param {...Function} fns any number of functions which will be injected using the injector. - */ - - - - var ErrorAddingDeclarationLocationStack = function(e, errorForStack) { - this.message = e.message; - this.name = e.name; - if (e.line) this.line = e.line; - if (e.sourceId) this.sourceId = e.sourceId; - if (e.stack && errorForStack) - this.stack = e.stack + '\n' + errorForStack.stack; - if (e.stackArray) this.stackArray = e.stackArray; - }; - ErrorAddingDeclarationLocationStack.prototype.toString = Error.prototype.toString; - - window.inject = angular.mock.inject = function() { - var blockFns = Array.prototype.slice.call(arguments, 0); - var errorForStack = new Error('Declaration Location'); - return isSpecRunning() ? workFn.call(currentSpec) : workFn; - ///////////////////// - function workFn() { - var modules = currentSpec.$modules || []; - var strictDi = !!currentSpec.$injectorStrict; - modules.unshift('ngMock'); - modules.unshift('ng'); - var injector = currentSpec.$injector; - if (!injector) { - if (strictDi) { - // If strictDi is enabled, annotate the providerInjector blocks - angular.forEach(modules, function(moduleFn) { - if (typeof moduleFn === "function") { - angular.injector.$$annotate(moduleFn); - } - }); - } - injector = currentSpec.$injector = angular.injector(modules, strictDi); - currentSpec.$injectorStrict = strictDi; - } - for (var i = 0, ii = blockFns.length; i < ii; i++) { - if (currentSpec.$injectorStrict) { - // If the injector is strict / strictDi, and the spec wants to inject using automatic - // annotation, then annotate the function here. - injector.annotate(blockFns[i]); - } - try { - /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */ - injector.invoke(blockFns[i] || angular.noop, this); - /* jshint +W040 */ - } catch (e) { - if (e.stack && errorForStack) { - throw new ErrorAddingDeclarationLocationStack(e, errorForStack); - } - throw e; - } finally { - errorForStack = null; - } - } - } - }; - - - angular.mock.inject.strictDi = function(value) { - value = arguments.length ? !!value : true; - return isSpecRunning() ? workFn() : workFn; - - function workFn() { - if (value !== currentSpec.$injectorStrict) { - if (currentSpec.$injector) { - throw new Error('Injector already created, can not modify strict annotations'); - } else { - currentSpec.$injectorStrict = value; - } - } - } - }; -} - - -})(window, window.angular); diff --git a/src/main/webapp/bower_components/angular-mocks/bower.json b/src/main/webapp/bower_components/angular-mocks/bower.json deleted file mode 100644 index cd52be40d..000000000 --- a/src/main/webapp/bower_components/angular-mocks/bower.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "angular-mocks", - "version": "1.3.11", - "main": "./angular-mocks.js", - "ignore": [], - "dependencies": { - "angular": "1.3.11" - } -} diff --git a/src/main/webapp/bower_components/angular-mocks/package.json b/src/main/webapp/bower_components/angular-mocks/package.json deleted file mode 100644 index c32d09fbd..000000000 --- a/src/main/webapp/bower_components/angular-mocks/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "angular-mocks", - "version": "1.3.11", - "description": "AngularJS mocks for testing", - "main": "angular-mocks.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "https://github.com/angular/angular.js.git" - }, - "keywords": [ - "angular", - "framework", - "browser", - "mocks", - "testing", - "client-side" - ], - "author": "Angular Core Team ", - "license": "MIT", - "bugs": { - "url": "https://github.com/angular/angular.js/issues" - }, - "homepage": "http://angularjs.org" -} diff --git a/src/main/webapp/bower_components/angular-resource/.bower.json b/src/main/webapp/bower_components/angular-resource/.bower.json deleted file mode 100644 index 2ab3e3c66..000000000 --- a/src/main/webapp/bower_components/angular-resource/.bower.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "angular-resource", - "version": "1.3.11", - "main": "./angular-resource.js", - "ignore": [], - "dependencies": { - "angular": "1.3.11" - }, - "homepage": "https://github.com/angular/bower-angular-resource", - "_release": "1.3.11", - "_resolution": { - "type": "version", - "tag": "v1.3.11", - "commit": "b2ace539da53a66ca54ff88c145a12e9e1606355" - }, - "_source": "git://github.com/angular/bower-angular-resource.git", - "_target": "1.3.11", - "_originalSource": "angular-resource" -} \ No newline at end of file diff --git a/src/main/webapp/bower_components/angular-resource/README.md b/src/main/webapp/bower_components/angular-resource/README.md deleted file mode 100644 index b09e0a7b6..000000000 --- a/src/main/webapp/bower_components/angular-resource/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# packaged angular-resource - -This repo is for distribution on `npm` and `bower`. The source for this module is in the -[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngResource). -Please file issues and pull requests against that repo. - -## Install - -You can install this package either with `npm` or with `bower`. - -### npm - -```shell -npm install angular-resource -``` - -Add a ` -``` - -Then add `ngResource` as a dependency for your app: - -```javascript -angular.module('myApp', ['ngResource']); -``` - -Note that this package is not in CommonJS format, so doing `require('angular-resource')` will -return `undefined`. - -### bower - -```shell -bower install angular-resource -``` - -Add a ` -``` - -Then add `ngResource` as a dependency for your app: - -```javascript -angular.module('myApp', ['ngResource']); -``` - -## Documentation - -Documentation is available on the -[AngularJS docs site](http://docs.angularjs.org/api/ngResource). - -## License - -The MIT License - -Copyright (c) 2010-2012 Google, Inc. http://angularjs.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/src/main/webapp/bower_components/angular-resource/angular-resource.js b/src/main/webapp/bower_components/angular-resource/angular-resource.js deleted file mode 100644 index 6040d7979..000000000 --- a/src/main/webapp/bower_components/angular-resource/angular-resource.js +++ /dev/null @@ -1,667 +0,0 @@ -/** - * @license AngularJS v1.3.11 - * (c) 2010-2014 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular, undefined) {'use strict'; - -var $resourceMinErr = angular.$$minErr('$resource'); - -// Helper functions and regex to lookup a dotted path on an object -// stopping at undefined/null. The path must be composed of ASCII -// identifiers (just like $parse) -var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/; - -function isValidDottedPath(path) { - return (path != null && path !== '' && path !== 'hasOwnProperty' && - MEMBER_NAME_REGEX.test('.' + path)); -} - -function lookupDottedPath(obj, path) { - if (!isValidDottedPath(path)) { - throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path); - } - var keys = path.split('.'); - for (var i = 0, ii = keys.length; i < ii && obj !== undefined; i++) { - var key = keys[i]; - obj = (obj !== null) ? obj[key] : undefined; - } - return obj; -} - -/** - * Create a shallow copy of an object and clear other fields from the destination - */ -function shallowClearAndCopy(src, dst) { - dst = dst || {}; - - angular.forEach(dst, function(value, key) { - delete dst[key]; - }); - - for (var key in src) { - if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { - dst[key] = src[key]; - } - } - - return dst; -} - -/** - * @ngdoc module - * @name ngResource - * @description - * - * # ngResource - * - * The `ngResource` module provides interaction support with RESTful services - * via the $resource service. - * - * - *
- * - * See {@link ngResource.$resource `$resource`} for usage. - */ - -/** - * @ngdoc service - * @name $resource - * @requires $http - * - * @description - * A factory which creates a resource object that lets you interact with - * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources. - * - * The returned resource object has action methods which provide high-level behaviors without - * the need to interact with the low level {@link ng.$http $http} service. - * - * Requires the {@link ngResource `ngResource`} module to be installed. - * - * By default, trailing slashes will be stripped from the calculated URLs, - * which can pose problems with server backends that do not expect that - * behavior. This can be disabled by configuring the `$resourceProvider` like - * this: - * - * ```js - app.config(['$resourceProvider', function($resourceProvider) { - // Don't strip trailing slashes from calculated URLs - $resourceProvider.defaults.stripTrailingSlashes = false; - }]); - * ``` - * - * @param {string} url A parametrized URL template with parameters prefixed by `:` as in - * `/user/:username`. If you are using a URL with a port number (e.g. - * `http://example.com:8080/api`), it will be respected. - * - * If you are using a url with a suffix, just add the suffix, like this: - * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')` - * or even `$resource('http://example.com/resource/:resource_id.:format')` - * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be - * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you - * can escape it with `/\.`. - * - * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in - * `actions` methods. If any of the parameter value is a function, it will be executed every time - * when a param value needs to be obtained for a request (unless the param was overridden). - * - * Each key value in the parameter object is first bound to url template if present and then any - * excess keys are appended to the url search query after the `?`. - * - * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in - * URL `/path/greet?salutation=Hello`. - * - * If the parameter value is prefixed with `@` then the value for that parameter will be extracted - * from the corresponding property on the `data` object (provided when calling an action method). For - * example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of `someParam` - * will be `data.someProp`. - * - * @param {Object.=} actions Hash with declaration of custom actions that should extend - * the default set of resource actions. The declaration should be created in the format of {@link - * ng.$http#usage $http.config}: - * - * {action1: {method:?, params:?, isArray:?, headers:?, ...}, - * action2: {method:?, params:?, isArray:?, headers:?, ...}, - * ...} - * - * Where: - * - * - **`action`** – {string} – The name of action. This name becomes the name of the method on - * your resource object. - * - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`, - * `DELETE`, `JSONP`, etc). - * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of - * the parameter value is a function, it will be executed every time when a param value needs to - * be obtained for a request (unless the param was overridden). - * - **`url`** – {string} – action specific `url` override. The url templating is supported just - * like for the resource-level urls. - * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, - * see `returns` section. - * - **`transformRequest`** – - * `{function(data, headersGetter)|Array.}` – - * transform function or an array of such functions. The transform function takes the http - * request body and headers and returns its transformed (typically serialized) version. - * By default, transformRequest will contain one function that checks if the request data is - * an object and serializes to using `angular.toJson`. To prevent this behavior, set - * `transformRequest` to an empty array: `transformRequest: []` - * - **`transformResponse`** – - * `{function(data, headersGetter)|Array.}` – - * transform function or an array of such functions. The transform function takes the http - * response body and headers and returns its transformed (typically deserialized) version. - * By default, transformResponse will contain one function that checks if the response looks like - * a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior, set - * `transformResponse` to an empty array: `transformResponse: []` - * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the - * GET request, otherwise if a cache instance built with - * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for - * caching. - * - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that - * should abort the request when resolved. - * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the - * XHR object. See - * [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5) - * for more information. - * - **`responseType`** - `{string}` - see - * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType). - * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods - - * `response` and `responseError`. Both `response` and `responseError` interceptors get called - * with `http response` object. See {@link ng.$http $http interceptors}. - * - * @param {Object} options Hash with custom settings that should extend the - * default `$resourceProvider` behavior. The only supported option is - * - * Where: - * - * - **`stripTrailingSlashes`** – {boolean} – If true then the trailing - * slashes from any calculated URL will be stripped. (Defaults to true.) - * - * @returns {Object} A resource "class" object with methods for the default set of resource actions - * optionally extended with custom `actions`. The default set contains these actions: - * ```js - * { 'get': {method:'GET'}, - * 'save': {method:'POST'}, - * 'query': {method:'GET', isArray:true}, - * 'remove': {method:'DELETE'}, - * 'delete': {method:'DELETE'} }; - * ``` - * - * Calling these methods invoke an {@link ng.$http} with the specified http method, - * destination and parameters. When the data is returned from the server then the object is an - * instance of the resource class. The actions `save`, `remove` and `delete` are available on it - * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create, - * read, update, delete) on server-side data like this: - * ```js - * var User = $resource('/user/:userId', {userId:'@id'}); - * var user = User.get({userId:123}, function() { - * user.abc = true; - * user.$save(); - * }); - * ``` - * - * It is important to realize that invoking a $resource object method immediately returns an - * empty reference (object or array depending on `isArray`). Once the data is returned from the - * server the existing reference is populated with the actual data. This is a useful trick since - * usually the resource is assigned to a model which is then rendered by the view. Having an empty - * object results in no rendering, once the data arrives from the server then the object is - * populated with the data and the view automatically re-renders itself showing the new data. This - * means that in most cases one never has to write a callback function for the action methods. - * - * The action methods on the class object or instance object can be invoked with the following - * parameters: - * - * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])` - * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])` - * - non-GET instance actions: `instance.$action([parameters], [success], [error])` - * - * Success callback is called with (value, responseHeaders) arguments. Error callback is called - * with (httpResponse) argument. - * - * Class actions return empty instance (with additional properties below). - * Instance actions return promise of the action. - * - * The Resource instances and collection have these additional properties: - * - * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this - * instance or collection. - * - * On success, the promise is resolved with the same resource instance or collection object, - * updated with data from server. This makes it easy to use in - * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view - * rendering until the resource(s) are loaded. - * - * On failure, the promise is resolved with the {@link ng.$http http response} object, without - * the `resource` property. - * - * If an interceptor object was provided, the promise will instead be resolved with the value - * returned by the interceptor. - * - * - `$resolved`: `true` after first server interaction is completed (either with success or - * rejection), `false` before that. Knowing if the Resource has been resolved is useful in - * data-binding. - * - * @example - * - * # Credit card resource - * - * ```js - // Define CreditCard class - var CreditCard = $resource('/user/:userId/card/:cardId', - {userId:123, cardId:'@id'}, { - charge: {method:'POST', params:{charge:true}} - }); - - // We can retrieve a collection from the server - var cards = CreditCard.query(function() { - // GET: /user/123/card - // server returns: [ {id:456, number:'1234', name:'Smith'} ]; - - var card = cards[0]; - // each item is an instance of CreditCard - expect(card instanceof CreditCard).toEqual(true); - card.name = "J. Smith"; - // non GET methods are mapped onto the instances - card.$save(); - // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'} - // server returns: {id:456, number:'1234', name: 'J. Smith'}; - - // our custom method is mapped as well. - card.$charge({amount:9.99}); - // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'} - }); - - // we can create an instance as well - var newCard = new CreditCard({number:'0123'}); - newCard.name = "Mike Smith"; - newCard.$save(); - // POST: /user/123/card {number:'0123', name:'Mike Smith'} - // server returns: {id:789, number:'0123', name: 'Mike Smith'}; - expect(newCard.id).toEqual(789); - * ``` - * - * The object returned from this function execution is a resource "class" which has "static" method - * for each action in the definition. - * - * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and - * `headers`. - * When the data is returned from the server then the object is an instance of the resource type and - * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD - * operations (create, read, update, delete) on server-side data. - - ```js - var User = $resource('/user/:userId', {userId:'@id'}); - User.get({userId:123}, function(user) { - user.abc = true; - user.$save(); - }); - ``` - * - * It's worth noting that the success callback for `get`, `query` and other methods gets passed - * in the response that came from the server as well as $http header getter function, so one - * could rewrite the above example and get access to http headers as: - * - ```js - var User = $resource('/user/:userId', {userId:'@id'}); - User.get({userId:123}, function(u, getResponseHeaders){ - u.abc = true; - u.$save(function(u, putResponseHeaders) { - //u => saved user object - //putResponseHeaders => $http header getter - }); - }); - ``` - * - * You can also access the raw `$http` promise via the `$promise` property on the object returned - * - ``` - var User = $resource('/user/:userId', {userId:'@id'}); - User.get({userId:123}) - .$promise.then(function(user) { - $scope.user = user; - }); - ``` - - * # Creating a custom 'PUT' request - * In this example we create a custom method on our resource to make a PUT request - * ```js - * var app = angular.module('app', ['ngResource', 'ngRoute']); - * - * // Some APIs expect a PUT request in the format URL/object/ID - * // Here we are creating an 'update' method - * app.factory('Notes', ['$resource', function($resource) { - * return $resource('/notes/:id', null, - * { - * 'update': { method:'PUT' } - * }); - * }]); - * - * // In our controller we get the ID from the URL using ngRoute and $routeParams - * // We pass in $routeParams and our Notes factory along with $scope - * app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes', - function($scope, $routeParams, Notes) { - * // First get a note object from the factory - * var note = Notes.get({ id:$routeParams.id }); - * $id = note.id; - * - * // Now call update passing in the ID first then the object you are updating - * Notes.update({ id:$id }, note); - * - * // This will PUT /notes/ID with the note object in the request payload - * }]); - * ``` - */ -angular.module('ngResource', ['ng']). - provider('$resource', function() { - var provider = this; - - this.defaults = { - // Strip slashes by default - stripTrailingSlashes: true, - - // Default actions configuration - actions: { - 'get': {method: 'GET'}, - 'save': {method: 'POST'}, - 'query': {method: 'GET', isArray: true}, - 'remove': {method: 'DELETE'}, - 'delete': {method: 'DELETE'} - } - }; - - this.$get = ['$http', '$q', function($http, $q) { - - var noop = angular.noop, - forEach = angular.forEach, - extend = angular.extend, - copy = angular.copy, - isFunction = angular.isFunction; - - /** - * We need our custom method because encodeURIComponent is too aggressive and doesn't follow - * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set - * (pchar) allowed in path segments: - * segment = *pchar - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * pct-encoded = "%" HEXDIG HEXDIG - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - */ - function encodeUriSegment(val) { - return encodeUriQuery(val, true). - replace(/%26/gi, '&'). - replace(/%3D/gi, '='). - replace(/%2B/gi, '+'); - } - - - /** - * This method is intended for encoding *key* or *value* parts of query component. We need a - * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't - * have to be encoded per http://tools.ietf.org/html/rfc3986: - * query = *( pchar / "/" / "?" ) - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * pct-encoded = "%" HEXDIG HEXDIG - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - */ - function encodeUriQuery(val, pctEncodeSpaces) { - return encodeURIComponent(val). - replace(/%40/gi, '@'). - replace(/%3A/gi, ':'). - replace(/%24/g, '$'). - replace(/%2C/gi, ','). - replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); - } - - function Route(template, defaults) { - this.template = template; - this.defaults = extend({}, provider.defaults, defaults); - this.urlParams = {}; - } - - Route.prototype = { - setUrlParams: function(config, params, actionUrl) { - var self = this, - url = actionUrl || self.template, - val, - encodedVal; - - var urlParams = self.urlParams = {}; - forEach(url.split(/\W/), function(param) { - if (param === 'hasOwnProperty') { - throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name."); - } - if (!(new RegExp("^\\d+$").test(param)) && param && - (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) { - urlParams[param] = true; - } - }); - url = url.replace(/\\:/g, ':'); - - params = params || {}; - forEach(self.urlParams, function(_, urlParam) { - val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam]; - if (angular.isDefined(val) && val !== null) { - encodedVal = encodeUriSegment(val); - url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) { - return encodedVal + p1; - }); - } else { - url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match, - leadingSlashes, tail) { - if (tail.charAt(0) == '/') { - return tail; - } else { - return leadingSlashes + tail; - } - }); - } - }); - - // strip trailing slashes and set the url (unless this behavior is specifically disabled) - if (self.defaults.stripTrailingSlashes) { - url = url.replace(/\/+$/, '') || '/'; - } - - // then replace collapse `/.` if found in the last URL path segment before the query - // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x` - url = url.replace(/\/\.(?=\w+($|\?))/, '.'); - // replace escaped `/\.` with `/.` - config.url = url.replace(/\/\\\./, '/.'); - - - // set params - delegate param encoding to $http - forEach(params, function(value, key) { - if (!self.urlParams[key]) { - config.params = config.params || {}; - config.params[key] = value; - } - }); - } - }; - - - function resourceFactory(url, paramDefaults, actions, options) { - var route = new Route(url, options); - - actions = extend({}, provider.defaults.actions, actions); - - function extractParams(data, actionParams) { - var ids = {}; - actionParams = extend({}, paramDefaults, actionParams); - forEach(actionParams, function(value, key) { - if (isFunction(value)) { value = value(); } - ids[key] = value && value.charAt && value.charAt(0) == '@' ? - lookupDottedPath(data, value.substr(1)) : value; - }); - return ids; - } - - function defaultResponseInterceptor(response) { - return response.resource; - } - - function Resource(value) { - shallowClearAndCopy(value || {}, this); - } - - Resource.prototype.toJSON = function() { - var data = extend({}, this); - delete data.$promise; - delete data.$resolved; - return data; - }; - - forEach(actions, function(action, name) { - var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method); - - Resource[name] = function(a1, a2, a3, a4) { - var params = {}, data, success, error; - - /* jshint -W086 */ /* (purposefully fall through case statements) */ - switch (arguments.length) { - case 4: - error = a4; - success = a3; - //fallthrough - case 3: - case 2: - if (isFunction(a2)) { - if (isFunction(a1)) { - success = a1; - error = a2; - break; - } - - success = a2; - error = a3; - //fallthrough - } else { - params = a1; - data = a2; - success = a3; - break; - } - case 1: - if (isFunction(a1)) success = a1; - else if (hasBody) data = a1; - else params = a1; - break; - case 0: break; - default: - throw $resourceMinErr('badargs', - "Expected up to 4 arguments [params, data, success, error], got {0} arguments", - arguments.length); - } - /* jshint +W086 */ /* (purposefully fall through case statements) */ - - var isInstanceCall = this instanceof Resource; - var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data)); - var httpConfig = {}; - var responseInterceptor = action.interceptor && action.interceptor.response || - defaultResponseInterceptor; - var responseErrorInterceptor = action.interceptor && action.interceptor.responseError || - undefined; - - forEach(action, function(value, key) { - if (key != 'params' && key != 'isArray' && key != 'interceptor') { - httpConfig[key] = copy(value); - } - }); - - if (hasBody) httpConfig.data = data; - route.setUrlParams(httpConfig, - extend({}, extractParams(data, action.params || {}), params), - action.url); - - var promise = $http(httpConfig).then(function(response) { - var data = response.data, - promise = value.$promise; - - if (data) { - // Need to convert action.isArray to boolean in case it is undefined - // jshint -W018 - if (angular.isArray(data) !== (!!action.isArray)) { - throw $resourceMinErr('badcfg', - 'Error in resource configuration for action `{0}`. Expected response to ' + - 'contain an {1} but got an {2}', name, action.isArray ? 'array' : 'object', - angular.isArray(data) ? 'array' : 'object'); - } - // jshint +W018 - if (action.isArray) { - value.length = 0; - forEach(data, function(item) { - if (typeof item === "object") { - value.push(new Resource(item)); - } else { - // Valid JSON values may be string literals, and these should not be converted - // into objects. These items will not have access to the Resource prototype - // methods, but unfortunately there - value.push(item); - } - }); - } else { - shallowClearAndCopy(data, value); - value.$promise = promise; - } - } - - value.$resolved = true; - - response.resource = value; - - return response; - }, function(response) { - value.$resolved = true; - - (error || noop)(response); - - return $q.reject(response); - }); - - promise = promise.then( - function(response) { - var value = responseInterceptor(response); - (success || noop)(value, response.headers); - return value; - }, - responseErrorInterceptor); - - if (!isInstanceCall) { - // we are creating instance / collection - // - set the initial promise - // - return the instance / collection - value.$promise = promise; - value.$resolved = false; - - return value; - } - - // instance call - return promise; - }; - - - Resource.prototype['$' + name] = function(params, success, error) { - if (isFunction(params)) { - error = success; success = params; params = {}; - } - var result = Resource[name].call(this, params, this, success, error); - return result.$promise || result; - }; - }); - - Resource.bind = function(additionalParamDefaults) { - return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions); - }; - - return Resource; - } - - return resourceFactory; - }]; - }); - - -})(window, window.angular); diff --git a/src/main/webapp/bower_components/angular-resource/angular-resource.min.js b/src/main/webapp/bower_components/angular-resource/angular-resource.min.js deleted file mode 100644 index 880ac2872..000000000 --- a/src/main/webapp/bower_components/angular-resource/angular-resource.min.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - AngularJS v1.3.11 - (c) 2010-2014 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(I,d,B){'use strict';function D(f,q){q=q||{};d.forEach(q,function(d,h){delete q[h]});for(var h in f)!f.hasOwnProperty(h)||"$"===h.charAt(0)&&"$"===h.charAt(1)||(q[h]=f[h]);return q}var w=d.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;d.module("ngResource",["ng"]).provider("$resource",function(){var f=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}}; -this.$get=["$http","$q",function(q,h){function t(d,g){this.template=d;this.defaults=s({},f.defaults,g);this.urlParams={}}function v(x,g,l,m){function c(b,k){var c={};k=s({},g,k);r(k,function(a,k){u(a)&&(a=a());var d;if(a&&a.charAt&&"@"==a.charAt(0)){d=b;var e=a.substr(1);if(null==e||""===e||"hasOwnProperty"===e||!C.test("."+e))throw w("badmember",e);for(var e=e.split("."),n=0,g=e.length;n", - "license": "MIT", - "bugs": { - "url": "https://github.com/angular/angular.js/issues" - }, - "homepage": "http://angularjs.org" -} diff --git a/src/main/webapp/bower_components/angular-scenario/.bower.json b/src/main/webapp/bower_components/angular-scenario/.bower.json deleted file mode 100644 index c24ab1f85..000000000 --- a/src/main/webapp/bower_components/angular-scenario/.bower.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "angular-scenario", - "version": "1.3.11", - "main": "./angular-scenario.js", - "ignore": [], - "dependencies": { - "angular": "1.3.11" - }, - "homepage": "https://github.com/angular/bower-angular-scenario", - "_release": "1.3.11", - "_resolution": { - "type": "version", - "tag": "v1.3.11", - "commit": "9b452ee8978462acf5d60ab0e4873163175801e5" - }, - "_source": "git://github.com/angular/bower-angular-scenario.git", - "_target": "1.3.11", - "_originalSource": "angular-scenario" -} \ No newline at end of file diff --git a/src/main/webapp/bower_components/angular-scenario/README.md b/src/main/webapp/bower_components/angular-scenario/README.md deleted file mode 100644 index b58d56e1a..000000000 --- a/src/main/webapp/bower_components/angular-scenario/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# packaged angular-scenario - -This tool is now in maintenance mode. If you are starting a new project, please use -[Protractor](https://github.com/angular/protractor). Existing projects using scenario runner are -advised to migrate to protractor, as this tool is unlikely to receive updates. - -This repo is for distribution on `npm` and `bower`. The source for this module is in the -[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngScenario). -Please file issues and pull requests against that repo. - -## Install - -You can install this package either with `npm` or with `bower`. - -### npm - -```shell -npm install angular-scenario -``` - -The files are then available at `node_modules/angular-scenario/`. - -Note that this package is not in CommonJS format, so doing `require('angular-scenario')` will -return `undefined`. - -### bower - -```shell -bower install angular-scenario -``` - -The files are then available at `bower_components/angular-scenario/`. - -## Documentation - -Documentation is available on the -[AngularJS docs site](http://docs.angularjs.org/). - -## License - -The MIT License - -Copyright (c) 2010-2012 Google, Inc. http://angularjs.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/src/main/webapp/bower_components/angular-scenario/angular-scenario.js b/src/main/webapp/bower_components/angular-scenario/angular-scenario.js deleted file mode 100644 index 6e1a52a87..000000000 --- a/src/main/webapp/bower_components/angular-scenario/angular-scenario.js +++ /dev/null @@ -1,37470 +0,0 @@ -/*! - * jQuery JavaScript Library v2.1.1 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-05-01T17:11Z - */ - -(function( global, factory ) {'use strict'; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - // For CommonJS and CommonJS-like environments where a proper window is present, - // execute the factory and get jQuery - // For environments that do not inherently posses a window with a document - // (such as Node.js), expose a jQuery-making factory as module.exports - // This accentuates the need for the creation of a real window - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Can't do this because several apps including ASP.NET trace -// the stack via arguments.caller.callee and Firefox dies if -// you try to trace through "use strict" call chains. (#13335) -// Support: Firefox 18+ -// - -var arr = []; - -var slice = arr.slice; - -var concat = arr.concat; - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var support = {}; - - - -var - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - version = "2.1.1", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }, - - // Support: Android<4.1 - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([\da-z])/gi, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - -jQuery.fn = jQuery.prototype = { - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // Start with an empty selector - selector: "", - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num != null ? - - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - - // Return all the elements in a clean array - slice.call( this ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray, - - isWindow: function( obj ) { - return obj != null && obj === obj.window; - }, - - isNumeric: function( obj ) { - // parseFloat NaNs numeric-cast false positives (null|true|false|"") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; - }, - - isPlainObject: function( obj ) { - // Not plain objects: - // - Any object or value whose internal [[Class]] property is not "[object Object]" - // - DOM nodes - // - window - if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.constructor && - !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { - return false; - } - - // If the function hasn't returned already, we're confident that - // |obj| is a plain object, created by {} or constructed with new Object - return true; - }, - - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - // Support: Android < 4.0, iOS < 6 (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call(obj) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - globalEval: function( code ) { - var script, - indirect = eval; - - code = jQuery.trim( code ); - - if ( code ) { - // If the code includes a valid, prologue position - // strict mode pragma, execute code by injecting a - // script tag into the document. - if ( code.indexOf("use strict") === 1 ) { - script = document.createElement("script"); - script.text = code; - document.head.appendChild( script ).parentNode.removeChild( script ); - } else { - // Otherwise, avoid the DOM node creation, insertion - // and removal by using an indirect global eval - indirect( code ); - } - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); - - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } - } - - return obj; - }, - - // Support: Android<4.1 - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, - i = 0, - length = elems.length, - isArray = isArraylike( elems ), - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var tmp, args, proxy; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: Date.now, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -function isArraylike( obj ) { - var length = obj.length, - type = jQuery.type( obj ); - - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.nodeType === 1 && length ) { - return true; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v1.10.19 - * http://sizzlejs.com/ - * - * Copyright 2013 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-04-18 - */ -(function( window ) { - -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + -(new Date()), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // General-purpose constants - strundefined = typeof undefined, - MAX_NEGATIVE = 1 << 31, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf if we can't use a native one - indexOf = arr.indexOf || function( elem ) { - var i = 0, - len = this.length; - for ( ; i < len; i++ ) { - if ( this[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/css3-syntax/#characters - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - - // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors - // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = characterEncoding.replace( "w", "w#" ), - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + characterEncoding + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - rescape = /'|\\/g, - - // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }; - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - // QSA vars - i, groups, old, nid, newContext, newSelector; - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - - context = context || document; - results = results || []; - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { - return []; - } - - if ( documentIsHTML && !seed ) { - - // Shortcuts - if ( (match = rquickExpr.exec( selector )) ) { - // Speed-up: Sizzle("#ID") - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document (jQuery #6963) - if ( elem && elem.parentNode ) { - // Handle the case where IE, Opera, and Webkit return items - // by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - } else { - // Context is not a document - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; - } - } - - // Speed-up: Sizzle("TAG") - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // QSA path - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType === 9 && selector; - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); - - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; - - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); - } - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; - newSelector = groups.join(","); - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result - */ -function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - // release memory in IE - div = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = attrs.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== strundefined && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, - doc = node ? node.ownerDocument || node : preferredDoc, - parent = doc.defaultView; - - // If no document and documentElement is available, return - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Set our document - document = doc; - docElem = doc.documentElement; - - // Support tests - documentIsHTML = !isXML( doc ); - - // Support: IE>8 - // If iframe document is assigned to "document" variable and if iframe has been reloaded, - // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 - // IE6-8 do not support the defaultView property so parent will be undefined - if ( parent && parent !== parent.top ) { - // IE11 does not have attachEvent, so all must suffer - if ( parent.addEventListener ) { - parent.addEventListener( "unload", function() { - setDocument(); - }, false ); - } else if ( parent.attachEvent ) { - parent.attachEvent( "onunload", function() { - setDocument(); - }); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) - support.attributes = assert(function( div ) { - div.className = "i"; - return !div.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( div ) { - div.appendChild( doc.createComment("") ); - return !div.getElementsByTagName("*").length; - }); - - // Check if getElementsByClassName can be trusted - support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { - div.innerHTML = "
"; - - // Support: Safari<4 - // Catch class over-caching - div.firstChild.className = "i"; - // Support: Opera<10 - // Catch gEBCN failure to find non-leading classes - return div.getElementsByClassName("i").length === 2; - }); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function( div ) { - docElem.appendChild( div ).id = expando; - return !doc.getElementsByName || !doc.getElementsByName( expando ).length; - }); - - // ID find and filter - if ( support.getById ) { - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== strundefined && documentIsHTML ) { - var m = context.getElementById( id ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [ m ] : []; - } - }; - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - } else { - // Support: IE6/7 - // getElementById is not reliable as a find shortcut - delete Expr.find["ID"]; - - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== strundefined ) { - return context.getElementsByTagName( tag ); - } - } : - function( tag, context ) { - var elem, - tmp = [], - i = 0, - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See http://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function( div ) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // http://bugs.jquery.com/ticket/12359 - div.innerHTML = ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( div.querySelectorAll("[msallowclip^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !div.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - }); - - assert(function( div ) { - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = doc.createElement("input"); - input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( div.querySelectorAll("[name=d]").length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":enabled").length ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - div.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( div ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( div, "div" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( div, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully does not implement inclusive descendent - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { - return -1; - } - if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - return a === doc ? -1 : - b === doc ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return doc; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch(e) {} - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[6] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, outerCache, node, diff, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - // Seek `elem` from a previously-cached index - outerCache = parent[ expando ] || (parent[ expando ] = {}); - cache = outerCache[ type ] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = cache[0] === dirruns && cache[2]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - // Use previously-cached element index if available - } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { - diff = cache[1]; - - // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) - } else { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { - // Cache the index of each encountered element - if ( useCache ) { - (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf.call( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function( selector ) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": function( elem ) { - return elem.disabled === false; - }, - - "disabled": function( elem ) { - return elem.disabled === true; - }, - - "checked": function( elem ) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } -}; - -Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( (tokens = []) ); - } - - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - checkNonElements = base && dir === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (oldCache = outerCache[ dir ]) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); - } else { - // Reuse newcache so results back-propagate to previous elements - outerCache[ dir ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { - return true; - } - } - } - } - } - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf.call( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if ( outermost ) { - outermostContext = context !== document && context; - } - - // Add elements passing elementMatchers directly to results - // Keep `i` a string if there are no elements so `matchedCount` will be "00" below - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // Apply set filters to unmatched elements - matchedCount += i; - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); - - results = results || []; - - // Try to minimize operations if there is no seed and only one group - if ( match.length === 1 ) { - - // Take a shortcut and set the context if the root selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - support.getById && context.nodeType === 9 && documentIsHTML && - Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; - -// Support: Chrome<14 -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( div1 ) { - // Should return 1, but returns 4 (following) - return div1.compareDocumentPosition( document.createElement("div") ) & 1; -}); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( div ) { - div.innerHTML = ""; - return div.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( div ) { - div.innerHTML = ""; - div.firstChild.setAttribute( "value", "" ); - return div.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( div ) { - return div.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - null; - } - }); -} - -return Sizzle; - -})( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.pseudos; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - - -var rneedsContext = jQuery.expr.match.needsContext; - -var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); - - - -var risSimple = /^.[^:#\[\.,]*$/; - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - }); - - } - - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - }); - - } - - if ( typeof qualifier === "string" ) { - if ( risSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - qualifier = jQuery.filter( qualifier, elements ); - } - - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; - }); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - })); -}; - -jQuery.fn.extend({ - find: function( selector ) { - var i, - len = this.length, - ret = [], - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); - }, - not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -}); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - init = jQuery.fn.init = function( selector, context ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - - // scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return typeof rootjQuery.ready !== "undefined" ? - rootjQuery.ready( selector ) : - // Execute immediately if ready is not present - selector( jQuery ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.extend({ - dir: function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; - }, - - sibling: function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; - } -}); - -jQuery.fn.extend({ - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter(function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( ; i < l; i++ ) { - for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { - // Always skip document fragments - if ( cur.nodeType < 11 && (pos ? - pos.index(cur) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors)) ) { - - matched.push( cur ); - break; - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.unique( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter(selector) - ); - } -}); - -function sibling( cur, dir ) { - while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} - return cur; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return elem.contentDocument || jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } - - if ( this.length > 1 ) { - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.unique( matched ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } - - return this.pushStack( matched ); - }; -}); -var rnotwhite = (/\S+/g); - - - -// String to Object options format cache -var optionsCache = {}; - -// Convert String-formatted options into Object-formatted ones and store in cache -function createOptions( options ) { - var object = optionsCache[ options ] = {}; - jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { - object[ flag ] = true; - }); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - ( optionsCache[ options ] || createOptions( options ) ) : - jQuery.extend( {}, options ); - - var // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list was already fired - fired, - // Flag to know if list is currently firing - firing, - // First callback to fire (used internally by add and fireWith) - firingStart, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = !options.once && [], - // Fire callbacks - fire = function( data ) { - memory = options.memory && data; - fired = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - firing = true; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { - memory = false; // To prevent further calls using add - break; - } - } - firing = false; - if ( list ) { - if ( stack ) { - if ( stack.length ) { - fire( stack.shift() ); - } - } else if ( memory ) { - list = []; - } else { - self.disable(); - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - // First, we save the current length - var start = list.length; - (function add( args ) { - jQuery.each( args, function( _, arg ) { - var type = jQuery.type( arg ); - if ( type === "function" ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && type !== "string" ) { - // Inspect recursively - add( arg ); - } - }); - })( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away - } else if ( memory ) { - firingStart = start; - fire( memory ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - // Handle firing indexes - if ( firing ) { - if ( index <= firingLength ) { - firingLength--; - } - if ( index <= firingIndex ) { - firingIndex--; - } - } - } - }); - } - return this; - }, - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); - }, - // Remove all callbacks from the list - empty: function() { - list = []; - firingLength = 0; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( list && ( !fired || stack ) ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - if ( firing ) { - stack.push( args ); - } else { - fire( args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -jQuery.extend({ - - Deferred: function( func ) { - var tuples = [ - // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], - [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], - [ "notify", "progress", jQuery.Callbacks("memory") ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - then: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - return jQuery.Deferred(function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ](function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); - } - }); - }); - fns = null; - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 3 ]; - - // promise[ done | fail | progress ] = list.add - promise[ tuple[1] ] = list.add; - - // Handle state - if ( stateString ) { - list.add(function() { - // state = [ resolved | rejected ] - state = stateString; - - // [ reject_list | resolve_list ].disable; progress_list.lock - }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); - } - - // deferred[ resolve | reject | notify ] - deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); - return this; - }; - deferred[ tuple[0] + "With" ] = list.fireWith; - }); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( subordinate /* , ..., subordinateN */ ) { - var i = 0, - resolveValues = slice.call( arguments ), - length = resolveValues.length, - - // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - - // the master Deferred. If resolveValues consist of only a single Deferred, just use that. - deferred = remaining === 1 ? subordinate : jQuery.Deferred(), - - // Update function for both resolve and progress values - updateFunc = function( i, contexts, values ) { - return function( value ) { - contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( values === progressValues ) { - deferred.notifyWith( contexts, values ); - } else if ( !( --remaining ) ) { - deferred.resolveWith( contexts, values ); - } - }; - }, - - progressValues, progressContexts, resolveContexts; - - // add listeners to Deferred subordinates; treat others as resolved - if ( length > 1 ) { - progressValues = new Array( length ); - progressContexts = new Array( length ); - resolveContexts = new Array( length ); - for ( ; i < length; i++ ) { - if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { - resolveValues[ i ].promise() - .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ) - .progress( updateFunc( i, progressContexts, progressValues ) ); - } else { - --remaining; - } - } - } - - // if we're not waiting on anything, resolve the master - if ( !remaining ) { - deferred.resolveWith( resolveContexts, resolveValues ); - } - - return deferred.promise(); - } -}); - - -// The deferred used on DOM ready -var readyList; - -jQuery.fn.ready = function( fn ) { - // Add the callback - jQuery.ready.promise().done( fn ); - - return this; -}; - -jQuery.extend({ - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - jQuery( document ).off( "ready" ); - } - } -}); - -/** - * The ready event handler and self cleanup method - */ -function completed() { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); - jQuery.ready(); -} - -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { - - readyList = jQuery.Deferred(); - - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // we once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); - - } else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); - } - } - return readyList.promise( obj ); -}; - -// Kick off the DOM ready check even if the user does not -jQuery.ready.promise(); - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - len ? fn( elems[0], key ) : emptyGet; -}; - - -/** - * Determines whether an object can have data - */ -jQuery.acceptData = function( owner ) { - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - /* jshint -W018 */ - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - -function Data() { - // Support: Android < 4, - // Old WebKit does not have Object.preventExtensions/freeze method, - // return new empty object instead with no [[set]] accessor - Object.defineProperty( this.cache = {}, 0, { - get: function() { - return {}; - } - }); - - this.expando = jQuery.expando + Math.random(); -} - -Data.uid = 1; -Data.accepts = jQuery.acceptData; - -Data.prototype = { - key: function( owner ) { - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return the key for a frozen object. - if ( !Data.accepts( owner ) ) { - return 0; - } - - var descriptor = {}, - // Check if the owner object already has a cache key - unlock = owner[ this.expando ]; - - // If not, create one - if ( !unlock ) { - unlock = Data.uid++; - - // Secure it in a non-enumerable, non-writable property - try { - descriptor[ this.expando ] = { value: unlock }; - Object.defineProperties( owner, descriptor ); - - // Support: Android < 4 - // Fallback to a less secure definition - } catch ( e ) { - descriptor[ this.expando ] = unlock; - jQuery.extend( owner, descriptor ); - } - } - - // Ensure the cache object - if ( !this.cache[ unlock ] ) { - this.cache[ unlock ] = {}; - } - - return unlock; - }, - set: function( owner, data, value ) { - var prop, - // There may be an unlock assigned to this node, - // if there is no entry for this "owner", create one inline - // and set the unlock as though an owner entry had always existed - unlock = this.key( owner ), - cache = this.cache[ unlock ]; - - // Handle: [ owner, key, value ] args - if ( typeof data === "string" ) { - cache[ data ] = value; - - // Handle: [ owner, { properties } ] args - } else { - // Fresh assignments by object are shallow copied - if ( jQuery.isEmptyObject( cache ) ) { - jQuery.extend( this.cache[ unlock ], data ); - // Otherwise, copy the properties one-by-one to the cache object - } else { - for ( prop in data ) { - cache[ prop ] = data[ prop ]; - } - } - } - return cache; - }, - get: function( owner, key ) { - // Either a valid cache is found, or will be created. - // New caches will be created and the unlock returned, - // allowing direct access to the newly created - // empty data object. A valid owner object must be provided. - var cache = this.cache[ this.key( owner ) ]; - - return key === undefined ? - cache : cache[ key ]; - }, - access: function( owner, key, value ) { - var stored; - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ((key && typeof key === "string") && value === undefined) ) { - - stored = this.get( owner, key ); - - return stored !== undefined ? - stored : this.get( owner, jQuery.camelCase(key) ); - } - - // [*]When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, name, camel, - unlock = this.key( owner ), - cache = this.cache[ unlock ]; - - if ( key === undefined ) { - this.cache[ unlock ] = {}; - - } else { - // Support array or space separated string of keys - if ( jQuery.isArray( key ) ) { - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = key.concat( key.map( jQuery.camelCase ) ); - } else { - camel = jQuery.camelCase( key ); - // Try the string as a key before any manipulation - if ( key in cache ) { - name = [ key, camel ]; - } else { - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - name = camel; - name = name in cache ? - [ name ] : ( name.match( rnotwhite ) || [] ); - } - } - - i = name.length; - while ( i-- ) { - delete cache[ name[ i ] ]; - } - } - }, - hasData: function( owner ) { - return !jQuery.isEmptyObject( - this.cache[ owner[ this.expando ] ] || {} - ); - }, - discard: function( owner ) { - if ( owner[ this.expando ] ) { - delete this.cache[ owner[ this.expando ] ]; - } - } -}; -var data_priv = new Data(); - -var data_user = new Data(); - - - -/* - Implementation Summary - - 1. Enforce API surface and semantic compatibility with 1.9.x branch - 2. Improve the module's maintainability by reducing the storage - paths to a single mechanism. - 3. Use the same single mechanism to support "private" and "user" data. - 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) - 5. Avoid exposing implementation details on user objects (eg. expando properties) - 6. Provide a clear path for implementation upgrade to WeakMap in 2014 -*/ -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /([A-Z])/g; - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - data_user.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend({ - hasData: function( elem ) { - return data_user.hasData( elem ) || data_priv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return data_user.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - data_user.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to data_priv methods, these can be deprecated. - _data: function( elem, name, data ) { - return data_priv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - data_priv.remove( elem, name ); - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = data_user.get( elem ); - - if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE11+ - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice(5) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - data_priv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each(function() { - data_user.set( this, key ); - }); - } - - return access( this, function( value ) { - var data, - camelKey = jQuery.camelCase( key ); - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - // Attempt to get data from the cache - // with the key as-is - data = data_user.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to get data from the cache - // with the key camelized - data = data_user.get( elem, camelKey ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, camelKey, undefined ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each(function() { - // First, attempt to store a copy or reference of any - // data that might've been store with a camelCased key. - var data = data_user.get( this, camelKey ); - - // For HTML5 data-* attribute interop, we have to - // store property names with dashes in a camelCase form. - // This might not apply to all properties...* - data_user.set( this, camelKey, value ); - - // *... In the case of properties that might _actually_ - // have dashes, we need to also store a copy of that - // unchanged property. - if ( key.indexOf("-") !== -1 && data !== undefined ) { - data_user.set( this, key, value ); - } - }); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each(function() { - data_user.remove( this, key ); - }); - } -}); - - -jQuery.extend({ - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = data_priv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || jQuery.isArray( data ) ) { - queue = data_priv.access( elem, type, jQuery.makeArray(data) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // not intended for public consumption - generates a queueHooks object, or returns the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return data_priv.get( elem, key ) || data_priv.access( elem, key, { - empty: jQuery.Callbacks("once memory").add(function() { - data_priv.remove( elem, [ type + "queue", key ] ); - }) - }); - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); - } - - return data === undefined ? - this : - this.each(function() { - var queue = jQuery.queue( this, type, data ); - - // ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = data_priv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -}); -var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var isHidden = function( elem, el ) { - // isHidden might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); - }; - -var rcheckableType = (/^(?:checkbox|radio)$/i); - - - -(function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // #11217 - WebKit loses check when the name is after the checked attribute - // Support: Windows Web Apps (WWA) - // `name` and `type` need .setAttribute for WWA - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 - // old WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Make sure textarea (and checkbox) defaultValue is properly cloned - // Support: IE9-IE11+ - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -})(); -var strundefined = typeof undefined; - - - -support.focusinBubbles = "onfocusin" in window; - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = data_priv.get( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !(events = elemData.events) ) { - events = elemData.events = {}; - } - if ( !(eventHandle = elemData.handle) ) { - eventHandle = elemData.handle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !(handlers = events[ type ]) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = data_priv.hasData( elem ) && data_priv.get( elem ); - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - data_priv.remove( elem, "events" ); - } - }, - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.namespace_re = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === (elem.ownerDocument || document) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && jQuery.acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && - jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event ); - - var i, j, ret, matched, handleObj, - handlerQueue = [], - args = slice.call( arguments ), - handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( (event.result = ret) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, matches, sel, handleObj, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - // Black-hole SVG instance trees (#13180) - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.disabled !== true || event.type !== "click" ) { - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matches[ sel ] === undefined ) { - matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matches[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( delegateCount < handlers.length ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); - } - - return handlerQueue; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var eventDoc, doc, body, - button = original.button; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, copy, - type = event.type, - originalEvent = event, - fixHook = this.fixHooks[ type ]; - - if ( !fixHook ) { - this.fixHooks[ type ] = fixHook = - rmouseEvent.test( type ) ? this.mouseHooks : - rkeyEvent.test( type ) ? this.keyHooks : - {}; - } - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = new jQuery.Event( originalEvent ); - - i = copy.length; - while ( i-- ) { - prop = copy[ i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Support: Cordova 2.5 (WebKit) (#13255) - // All events should have a target; Cordova deviceready doesn't - if ( !event.target ) { - event.target = document; - } - - // Support: Safari 6.0+, Chrome < 28 - // Target should not be a text node (#504, #13143) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; - }, - - special: { - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -jQuery.removeEvent = function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } -}; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - // Support: Android < 4.0 - src.returnValue === false ? - returnTrue : - returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && e.preventDefault ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && e.stopPropagation ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && e.stopImmediatePropagation ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -// Support: Chrome 15+ -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// Create "bubbling" focus and blur events -// Support: Firefox, Chrome, Safari -if ( !support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = data_priv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - data_priv.remove( doc, fix ); - - } else { - data_priv.access( doc, fix, attaches ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - var elem = this[0]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -}); - - -var - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - rtagName = /<([\w:]+)/, - rhtml = /<|&#?\w+;/, - rnoInnerhtml = /<(?:script|style|link)/i, - // checked="checked" or checked - rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - rscriptType = /^$|\/(?:java|ecma)script/i, - rscriptTypeMasked = /^true\/(.*)/, - rcleanScript = /^\s*\s*$/g, - - // We have to close these tags to support XHTML (#13200) - wrapMap = { - - // Support: IE 9 - option: [ 1, "" ], - - thead: [ 1, "", "
" ], - col: [ 2, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - _default: [ 0, "", "" ] - }; - -// Support: IE 9 -wrapMap.optgroup = wrapMap.option; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: 1.x compatibility -// Manipulating tables requires a tbody -function manipulationTarget( elem, content ) { - return jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? - - elem.getElementsByTagName("tbody")[0] || - elem.appendChild( elem.ownerDocument.createElement("tbody") ) : - elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - - if ( match ) { - elem.type = match[ 1 ]; - } else { - elem.removeAttribute("type"); - } - - return elem; -} - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - data_priv.set( - elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) - ); - } -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( data_priv.hasData( src ) ) { - pdataOld = data_priv.access( src ); - pdataCur = data_priv.set( dest, pdataOld ); - events = pdataOld.events; - - if ( events ) { - delete pdataCur.handle; - pdataCur.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( data_user.hasData( src ) ) { - udataOld = data_user.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - data_user.set( dest, udataCur ); - } -} - -function getAll( context, tag ) { - var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : - context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : - []; - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], ret ) : - ret; -} - -// Support: IE >= 9 -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -jQuery.extend({ - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = jQuery.contains( elem.ownerDocument, elem ); - - // Support: IE >= 9 - // Fix Cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - buildFragment: function( elems, context, scripts, selection ) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - // Support: QtWebKit - // jQuery.merge because push.apply(_, arraylike) throws - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement("div") ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: QtWebKit - // jQuery.merge because push.apply(_, arraylike) throws - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Fixes #12346 - // Support: Webkit, IE - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( (elem = nodes[ i++ ]) ) { - - // #4087 - If origin and destination elements are the same, and this is - // that element, do not do anything - if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( (elem = tmp[ j++ ]) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; - }, - - cleanData: function( elems ) { - var data, elem, type, key, - special = jQuery.event.special, - i = 0; - - for ( ; (elem = elems[ i ]) !== undefined; i++ ) { - if ( jQuery.acceptData( elem ) ) { - key = elem[ data_priv.expando ]; - - if ( key && (data = data_priv.cache[ key ]) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - if ( data_priv.cache[ key ] ) { - // Discard any remaining `private` data - delete data_priv.cache[ key ]; - } - } - } - // Discard any remaining `user` data - delete data_user.cache[ elem[ data_user.expando ] ]; - } - } -}); - -jQuery.fn.extend({ - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each(function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - }); - }, null, value, arguments.length ); - }, - - append: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - }); - }, - - prepend: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - }); - }, - - before: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - }); - }, - - after: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - }); - }, - - remove: function( selector, keepData /* Internal Use Only */ ) { - var elem, - elems = selector ? jQuery.filter( selector, this ) : this, - i = 0; - - for ( ; (elem = elems[i]) != null; i++ ) { - if ( !keepData && elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem ) ); - } - - if ( elem.parentNode ) { - if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { - setGlobalEval( getAll( elem, "script" ) ); - } - elem.parentNode.removeChild( elem ); - } - } - - return this; - }, - - empty: function() { - var elem, - i = 0; - - for ( ; (elem = this[i]) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map(function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - }); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = value.replace( rxhtmlTag, "<$1>" ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var arg = arguments[ 0 ]; - - // Make the changes, replacing each context element with the new content - this.domManip( arguments, function( elem ) { - arg = this.parentNode; - - jQuery.cleanData( getAll( this ) ); - - if ( arg ) { - arg.replaceChild( elem, this ); - } - }); - - // Force removal if there was no new content (e.g., from empty arguments) - return arg && (arg.length || arg.nodeType) ? this : this.remove(); - }, - - detach: function( selector ) { - return this.remove( selector, true ); - }, - - domManip: function( args, callback ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = this.length, - set = this, - iNoClone = l - 1, - value = args[ 0 ], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return this.each(function( index ) { - var self = set.eq( index ); - if ( isFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - self.domManip( args, callback ); - }); - } - - if ( l ) { - fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - if ( first ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - // Support: QtWebKit - // jQuery.merge because push.apply(_, arraylike) throws - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( this[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - - if ( node.src ) { - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); - } - } - } - } - } - } - - return this; - } -}); - -jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: QtWebKit - // .get() because push.apply(_, arraylike) throws - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -}); - - -var iframe, - elemdisplay = {}; - -/** - * Retrieve the actual display of a element - * @param {String} name nodeName of the element - * @param {Object} doc Document object - */ -// Called only from within defaultDisplay -function actualDisplay( name, doc ) { - var style, - elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - - // getDefaultComputedStyle might be reliably used only on attached element - display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? - - // Use of this method is a temporary fix (more like optmization) until something better comes along, - // since it was removed from specification and supported only in FF - style.display : jQuery.css( elem[ 0 ], "display" ); - - // We don't have any data stored on the element, - // so use "detach" method as fast way to get rid of the element - elem.detach(); - - return display; -} - -/** - * Try to determine the default display value of an element - * @param {String} nodeName - */ -function defaultDisplay( nodeName ) { - var doc = document, - display = elemdisplay[ nodeName ]; - - if ( !display ) { - display = actualDisplay( nodeName, doc ); - - // If the simple way fails, read from inside an iframe - if ( display === "none" || !display ) { - - // Use the already-created iframe if possible - iframe = (iframe || jQuery( " - -
  • - -
  • - -
  • - -
  • - - - - -
    - -
    - -

    Introducing Bootstrap.

    - - -
    -
    - -

    By nerds, for nerds.

    -

    Built at Twitter by @mdo and @fat, Bootstrap utilizes LESS CSS, is compiled via Node, and is managed through GitHub to help nerds do awesome stuff on the web.

    -
    -
    - -

    Made for everyone.

    -

    Bootstrap was made to not only look and behave great in the latest desktop browsers (as well as IE7!), but in tablet and smartphone browsers via responsive CSS as well.

    -
    -
    - -

    Packed with features.

    -

    A 12-column responsive grid, dozens of components, JavaScript plugins, typography, form controls, and even a web-based Customizer to make Bootstrap your own.

    -
    -
    - -
    - -

    Built with Bootstrap.

    - -
    - -
    - -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/webapp/bower_components/bootstrap/docs/javascript.html b/src/main/webapp/bower_components/bootstrap/docs/javascript.html deleted file mode 100644 index f4957d91c..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/javascript.html +++ /dev/null @@ -1,1780 +0,0 @@ - - - - - Javascript · Bootstrap - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -

    JavaScript

    -

    Bring Bootstrap's components to life—now with 13 custom jQuery plugins. -

    -
    - -
    - - -
    - -
    - - - -
    - - -

    Individual or compiled

    -

    Plugins can be included individually (though some have required dependencies), or all at once. Both bootstrap.js and bootstrap.min.js contain all plugins in a single file.

    - -

    Data attributes

    -

    You can use all Bootstrap plugins purely through the markup API without writing a single line of JavaScript. This is Bootstrap's first class API and should be your first consideration when using a plugin.

    - -

    That said, in some situations it may be desirable to turn this functionality off. Therefore, we also provide the ability to disable the data attribute API by unbinding all events on the body namespaced with `'data-api'`. This looks like this: -

    $('body').off('.data-api')
    - -

    Alternatively, to target a specific plugin, just include the plugin's name as a namespace along with the data-api namespace like this:

    -
    $('body').off('.alert.data-api')
    - -

    Programmatic API

    -

    We also believe you should be able to use all Bootstrap plugins purely through the JavaScript API. All public APIs are single, chainable methods, and return the collection acted upon.

    -
    $(".btn.danger").button("toggle").addClass("fat")
    -

    All methods should accept an optional options object, a string which targets a particular method, or nothing (which initiates a plugin with default behavior):

    -
    -$("#myModal").modal()                       // initialized with defaults
    -$("#myModal").modal({ keyboard: false })   // initialized with no keyboard
    -$("#myModal").modal('show')                // initializes and invokes show immediately

    -
    -

    Each plugin also exposes its raw constructor on a `Constructor` property: $.fn.popover.Constructor. If you'd like to get a particular plugin instance, retrieve it directly from an element: $('[rel=popover]').data('popover').

    - -

    No Conflict

    -

    Sometimes it is necessary to use Bootstrap plugins with other UI frameworks. In these circumstances, namespace collisions can occasionally occur. If this happens, you may call .noConflict on the plugin you wish to revert the value of.

    - -
    -var bootstrapButton = $.fn.button.noConflict() // return $.fn.button to previously assigned value
    -$.fn.bootstrapBtn = bootstrapButton            // give $().bootstrapBtn the bootstrap functionality
    -
    - -

    Events

    -

    Bootstrap provides custom events for most plugin's unique actions. Generally, these come in an infinitive and past participle form - where the infinitive (ex. show) is triggered at the start of an event, and its past participle form (ex. shown) is trigger on the completion of an action.

    -

    All infinitive events provide preventDefault functionality. This provides the ability to stop the execution of an action before it starts.

    -
    -$('#myModal').on('show', function (e) {
    -    if (!data) return e.preventDefault() // stops modal from being shown
    -})
    -
    -
    - - - - -
    - -

    About transitions

    -

    For simple transition effects, include bootstrap-transition.js once alongside the other JS files. If you're using the compiled (or minified) bootstrap.js, there is no need to include this—it's already there.

    -

    Use cases

    -

    A few examples of the transition plugin:

    -
      -
    • Sliding or fading in modals
    • -
    • Fading out tabs
    • -
    • Fading out alerts
    • -
    • Sliding carousel panes
    • -
    - -
    - - - - -
    - - - -

    Examples

    -

    Modals are streamlined, but flexible, dialog prompts with the minimum required functionality and smart defaults.

    - -

    Static example

    -

    A rendered modal with header, body, and set of actions in the footer.

    -
    - -
    -
    -<div class="modal hide fade">
    -  <div class="modal-header">
    -    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    -    <h3>Modal header</h3>
    -  </div>
    -  <div class="modal-body">
    -    <p>One fine body…</p>
    -  </div>
    -  <div class="modal-footer">
    -    <a href="#" class="btn">Close</a>
    -    <a href="#" class="btn btn-primary">Save changes</a>
    -  </div>
    -</div>
    -
    - -

    Live demo

    -

    Toggle a modal via JavaScript by clicking the button below. It will slide down and fade in from the top of the page.

    - - - -
    -<!-- Button to trigger modal -->
    -<a href="#myModal" role="button" class="btn" data-toggle="modal">Launch demo modal</a>
    -
    -<!-- Modal -->
    -<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    -  <div class="modal-header">
    -    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    -    <h3 id="myModalLabel">Modal header</h3>
    -  </div>
    -  <div class="modal-body">
    -    <p>One fine body…</p>
    -  </div>
    -  <div class="modal-footer">
    -    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    -    <button class="btn btn-primary">Save changes</button>
    -  </div>
    -</div>
    -
    - - -
    - - -

    Usage

    - -

    Via data attributes

    -

    Activate a modal without writing JavaScript. Set data-toggle="modal" on a controller element, like a button, along with a data-target="#foo" or href="#foo" to target a specific modal to toggle.

    -
    <button type="button" data-toggle="modal" data-target="#myModal">Launch modal</button>
    - -

    Via JavaScript

    -

    Call a modal with id myModal with a single line of JavaScript:

    -
    $('#myModal').modal(options)
    - -

    Options

    -

    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-backdrop="".

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Nametypedefaultdescription
    backdropbooleantrueIncludes a modal-backdrop element. Alternatively, specify static for a backdrop which doesn't close the modal on click.
    keyboardbooleantrueCloses the modal when escape key is pressed
    showbooleantrueShows the modal when initialized.
    remotepathfalse

    If a remote url is provided, content will be loaded via jQuery's load method and injected into the .modal-body. If you're using the data api, you may alternatively use the href tag to specify the remote source. An example of this is shown below:

    -
    <a data-toggle="modal" href="remote.html" data-target="#modal">click me</a>
    - -

    Methods

    -

    .modal(options)

    -

    Activates your content as a modal. Accepts an optional options object.

    -
    -$('#myModal').modal({
    -  keyboard: false
    -})
    -
    -

    .modal('toggle')

    -

    Manually toggles a modal.

    -
    $('#myModal').modal('toggle')
    -

    .modal('show')

    -

    Manually opens a modal.

    -
    $('#myModal').modal('show')
    -

    .modal('hide')

    -

    Manually hides a modal.

    -
    $('#myModal').modal('hide')
    -

    Events

    -

    Bootstrap's modal class exposes a few events for hooking into modal functionality.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    EventDescription
    showThis event fires immediately when the show instance method is called.
    shownThis event is fired when the modal has been made visible to the user (will wait for css transitions to complete).
    hideThis event is fired immediately when the hide instance method has been called.
    hiddenThis event is fired when the modal has finished being hidden from the user (will wait for css transitions to complete).
    -
    -$('#myModal').on('hidden', function () {
    -  // do something…
    -})
    -
    -
    - - - - - - - - - -
    - - - -

    Example in navbar

    -

    The ScrollSpy plugin is for automatically updating nav targets based on scroll position. Scroll the area below the navbar and watch the active class change. The dropdown sub items will be highlighted as well.

    -
    - -
    -

    @fat

    -

    Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

    -

    @mdo

    -

    Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard. Freegan beard aliqua cupidatat mcsweeney's vero. Cupidatat four loko nisi, ea helvetica nulla carles. Tattooed cosby sweater food truck, mcsweeney's quis non freegan vinyl. Lo-fi wes anderson +1 sartorial. Carles non aesthetic exercitation quis gentrify. Brooklyn adipisicing craft beer vice keytar deserunt.

    -

    one

    -

    Occaecat commodo aliqua delectus. Fap craft beer deserunt skateboard ea. Lomo bicycle rights adipisicing banh mi, velit ea sunt next level locavore single-origin coffee in magna veniam. High life id vinyl, echo park consequat quis aliquip banh mi pitchfork. Vero VHS est adipisicing. Consectetur nisi DIY minim messenger bag. Cred ex in, sustainable delectus consectetur fanny pack iphone.

    -

    two

    -

    In incididunt echo park, officia deserunt mcsweeney's proident master cleanse thundercats sapiente veniam. Excepteur VHS elit, proident shoreditch +1 biodiesel laborum craft beer. Single-origin coffee wayfarers irure four loko, cupidatat terry richardson master cleanse. Assumenda you probably haven't heard of them art party fanny pack, tattooed nulla cardigan tempor ad. Proident wolf nesciunt sartorial keffiyeh eu banh mi sustainable. Elit wolf voluptate, lo-fi ea portland before they sold out four loko. Locavore enim nostrud mlkshk brooklyn nesciunt.

    -

    three

    -

    Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

    -

    Keytar twee blog, culpa messenger bag marfa whatever delectus food truck. Sapiente synth id assumenda. Locavore sed helvetica cliche irony, thundercats you probably haven't heard of them consequat hoodie gluten-free lo-fi fap aliquip. Labore elit placeat before they sold out, terry richardson proident brunch nesciunt quis cosby sweater pariatur keffiyeh ut helvetica artisan. Cardigan craft beer seitan readymade velit. VHS chambray laboris tempor veniam. Anim mollit minim commodo ullamco thundercats. -

    -
    -
    - - -
    - - -

    Usage

    - -

    Via data attributes

    -

    To easily add scrollspy behavior to your topbar navigation, just add data-spy="scroll" to the element you want to spy on (most typically this would be the body) and data-target=".navbar" to select which nav to use. You'll want to use scrollspy with a .nav component.

    -
    <body data-spy="scroll" data-target=".navbar">...</body>
    - -

    Via JavaScript

    -

    Call the scrollspy via JavaScript:

    -
    $('#navbar').scrollspy()
    - -
    - Heads up! - Navbar links must have resolvable id targets. For example, a <a href="#home">home</a> must correspond to something in the dom like <div id="home"></div>. -
    - -

    Methods

    -

    .scrollspy('refresh')

    -

    When using scrollspy in conjunction with adding or removing of elements from the DOM, you'll need to call the refresh method like so:

    -
    -$('[data-spy="scroll"]').each(function () {
    -  var $spy = $(this).scrollspy('refresh')
    -});
    -
    - -

    Options

    -

    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-offset="".

    - - - - - - - - - - - - - - - - - -
    Nametypedefaultdescription
    offsetnumber10Pixels to offset from top when calculating position of scroll.
    - -

    Events

    - - - - - - - - - - - - - -
    EventDescription
    activateThis event fires whenever a new item becomes activated by the scrollspy.
    -
    - - - - -
    - - - -

    Example tabs

    -

    Add quick, dynamic tab functionality to transition through panes of local content, even via dropdown menus.

    -
    - -
    -
    -

    Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.

    -
    -
    -

    Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.

    -
    - - -
    -
    - - -
    - - -

    Usage

    -

    Enable tabbable tabs via JavaScript (each tab needs to be activated individually):

    -
    -$('#myTab a').click(function (e) {
    -  e.preventDefault();
    -  $(this).tab('show');
    -})
    -

    You can activate individual tabs in several ways:

    -
    -$('#myTab a[href="#profile"]').tab('show'); // Select tab by name
    -$('#myTab a:first').tab('show'); // Select first tab
    -$('#myTab a:last').tab('show'); // Select last tab
    -$('#myTab li:eq(2) a').tab('show'); // Select third tab (0-indexed)
    -
    - -

    Markup

    -

    You can activate a tab or pill navigation without writing any JavaScript by simply specifying data-toggle="tab" or data-toggle="pill" on an element. Adding the nav and nav-tabs classes to the tab ul will apply the Bootstrap tab styling.

    -
    -<ul class="nav nav-tabs">
    -  <li><a href="#home" data-toggle="tab">Home</a></li>
    -  <li><a href="#profile" data-toggle="tab">Profile</a></li>
    -  <li><a href="#messages" data-toggle="tab">Messages</a></li>
    -  <li><a href="#settings" data-toggle="tab">Settings</a></li>
    -</ul>
    - -

    Methods

    -

    $().tab

    -

    - Activates a tab element and content container. Tab should have either a data-target or an href targeting a container node in the DOM. -

    -
    -<ul class="nav nav-tabs" id="myTab">
    -  <li class="active"><a href="#home">Home</a></li>
    -  <li><a href="#profile">Profile</a></li>
    -  <li><a href="#messages">Messages</a></li>
    -  <li><a href="#settings">Settings</a></li>
    -</ul>
    -
    -<div class="tab-content">
    -  <div class="tab-pane active" id="home">...</div>
    -  <div class="tab-pane" id="profile">...</div>
    -  <div class="tab-pane" id="messages">...</div>
    -  <div class="tab-pane" id="settings">...</div>
    -</div>
    -
    -<script>
    -  $(function () {
    -    $('#myTab a:last').tab('show');
    -  })
    -</script>
    -
    - -

    Events

    - - - - - - - - - - - - - - - - - -
    EventDescription
    showThis event fires on tab show, but before the new tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.
    shownThis event fires on tab show after a tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.
    -
    -$('a[data-toggle="tab"]').on('shown', function (e) {
    -  e.target // activated tab
    -  e.relatedTarget // previous tab
    -})
    -
    -
    - - - -
    - - - -

    Examples

    -

    Inspired by the excellent jQuery.tipsy plugin written by Jason Frame; Tooltips are an updated version, which don't rely on images, use CSS3 for animations, and data-attributes for local title storage.

    -

    For performance reasons, the tooltip and popover data-apis are opt in, meaning you must initialize them yourself.

    -

    Hover over the links below to see tooltips:

    -
    -

    Tight pants next level keffiyeh you probably haven't heard of them. Photo booth beard raw denim letterpress vegan messenger bag stumptown. Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit american apparel have a terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo thundercats. Tofu biodiesel williamsburg marfa, four loko mcsweeney's cleanse vegan chambray. A really ironic artisan whatever keytar, scenester farm-to-table banksy Austin twitter handle freegan cred raw denim single-origin coffee viral. -

    -
    - -

    Four directions

    - - - -

    Tooltips in input groups

    -

    When using tooltips and popovers with the Bootstrap input groups, you'll have to set the container (documented below) option to avoid unwanted side effects.

    - -
    - - -

    Usage

    -

    Trigger the tooltip via JavaScript:

    -
    $('#example').tooltip(options)
    - -

    Options

    -

    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-animation="".

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Nametypedefaultdescription
    animationbooleantrueapply a css fade transition to the tooltip
    htmlbooleanfalseInsert html into the tooltip. If false, jquery's text method will be used to insert content into the dom. Use text if you're worried about XSS attacks.
    placementstring | function'top'how to position the tooltip - top | bottom | left | right
    selectorstringfalseIf a selector is provided, tooltip objects will be delegated to the specified targets.
    titlestring | function''default title value if `title` tag isn't present
    triggerstring'hover focus'how tooltip is triggered - click | hover | focus | manual. Note you case pass trigger mutliple, space seperated, trigger types.
    delaynumber | object0 -

    delay showing and hiding the tooltip (ms) - does not apply to manual trigger type

    -

    If a number is supplied, delay is applied to both hide/show

    -

    Object structure is: delay: { show: 500, hide: 100 }

    -
    containerstring | falsefalse -

    Appends the tooltip to a specific element container: 'body'

    -
    -
    - Heads up! - Options for individual tooltips can alternatively be specified through the use of data attributes. -
    - -

    Markup

    -
    <a href="#" data-toggle="tooltip" title="first tooltip">hover over me</a>
    - -

    Methods

    -

    $().tooltip(options)

    -

    Attaches a tooltip handler to an element collection.

    -

    .tooltip('show')

    -

    Reveals an element's tooltip.

    -
    $('#element').tooltip('show')
    -

    .tooltip('hide')

    -

    Hides an element's tooltip.

    -
    $('#element').tooltip('hide')
    -

    .tooltip('toggle')

    -

    Toggles an element's tooltip.

    -
    $('#element').tooltip('toggle')
    -

    .tooltip('destroy')

    -

    Hides and destroys an element's tooltip.

    -
    $('#element').tooltip('destroy')
    -
    - - - - -
    - - -

    Examples

    -

    Add small overlays of content, like those on the iPad, to any element for housing secondary information. Hover over the button to trigger the popover. Requires Tooltip to be included.

    - -

    Static popover

    -

    Four options are available: top, right, bottom, and left aligned.

    -
    -
    -
    -

    Popover top

    -
    -

    Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

    -
    -
    - -
    -
    -

    Popover right

    -
    -

    Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

    -
    -
    - -
    -
    -

    Popover bottom

    -
    -

    Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

    -
    -
    - -
    -
    -

    Popover left

    -
    -

    Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

    -
    -
    - -
    -
    -

    No markup shown as popovers are generated from JavaScript and content within a data attribute.

    - -

    Live demo

    - - -

    Four directions

    - - - -
    - - -

    Usage

    -

    Enable popovers via JavaScript:

    -
    $('#example').popover(options)
    - -

    Options

    -

    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-animation="".

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Nametypedefaultdescription
    animationbooleantrueapply a css fade transition to the tooltip
    htmlbooleanfalseInsert html into the popover. If false, jquery's text method will be used to insert content into the dom. Use text if you're worried about XSS attacks.
    placementstring | function'right'how to position the popover - top | bottom | left | right
    selectorstringfalseif a selector is provided, tooltip objects will be delegated to the specified targets
    triggerstring'click'how popover is triggered - click | hover | focus | manual
    titlestring | function''default title value if `title` attribute isn't present
    contentstring | function''default content value if `data-content` attribute isn't present
    delaynumber | object0 -

    delay showing and hiding the popover (ms) - does not apply to manual trigger type

    -

    If a number is supplied, delay is applied to both hide/show

    -

    Object structure is: delay: { show: 500, hide: 100 }

    -
    containerstring | falsefalse -

    Appends the popover to a specific element container: 'body'

    -
    -
    - Heads up! - Options for individual popovers can alternatively be specified through the use of data attributes. -
    - -

    Markup

    -

    For performance reasons, the Tooltip and Popover data-apis are opt in. If you would like to use them just specify a selector option.

    - -

    Methods

    -

    $().popover(options)

    -

    Initializes popovers for an element collection.

    -

    .popover('show')

    -

    Reveals an elements popover.

    -
    $('#element').popover('show')
    -

    .popover('hide')

    -

    Hides an elements popover.

    -
    $('#element').popover('hide')
    -

    .popover('toggle')

    -

    Toggles an elements popover.

    -
    $('#element').popover('toggle')
    -

    .popover('destroy')

    -

    Hides and destroys an element's popover.

    -
    $('#element').popover('destroy')
    -
    - - - - -
    - - - -

    Example alerts

    -

    Add dismiss functionality to all alert messages with this plugin.

    -
    -
    - - Holy guacamole! Best check yo self, you're not looking too good. -
    -
    - -
    -
    - -

    Oh snap! You got an error!

    -

    Change this and that and try again. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum.

    -

    - Take this action Or do this -

    -
    -
    - - -
    - - -

    Usage

    -

    Enable dismissal of an alert via JavaScript:

    -
    $(".alert").alert()
    - -

    Markup

    -

    Just add data-dismiss="alert" to your close button to automatically give an alert close functionality.

    -
    <a class="close" data-dismiss="alert" href="#">&times;</a>
    - -

    Methods

    -

    $().alert()

    -

    Wraps all alerts with close functionality. To have your alerts animate out when closed, make sure they have the .fade and .in class already applied to them.

    -

    .alert('close')

    -

    Closes an alert.

    -
    $(".alert").alert('close')
    - - -

    Events

    -

    Bootstrap's alert class exposes a few events for hooking into alert functionality.

    - - - - - - - - - - - - - - - - - -
    EventDescription
    closeThis event fires immediately when the close instance method is called.
    closedThis event is fired when the alert has been closed (will wait for css transitions to complete).
    -
    -$('#my-alert').bind('closed', function () {
    -  // do something…
    -})
    -
    -
    - - - - -
    - - -

    Example uses

    -

    Do more with buttons. Control button states or create groups of buttons for more components like toolbars.

    - -

    Stateful

    -

    Add data-loading-text="Loading..." to use a loading state on a button.

    -
    - -
    -
    <button type="button" class="btn btn-primary" data-loading-text="Loading...">Loading state</button>
    - -

    Single toggle

    -

    Add data-toggle="button" to activate toggling on a single button.

    -
    - -
    -
    <button type="button" class="btn btn-primary" data-toggle="button">Single Toggle</button>
    - -

    Checkbox

    -

    Add data-toggle="buttons-checkbox" for checkbox style toggling on btn-group.

    -
    -
    - - - -
    -
    -
    -<div class="btn-group" data-toggle="buttons-checkbox">
    -  <button type="button" class="btn btn-primary">Left</button>
    -  <button type="button" class="btn btn-primary">Middle</button>
    -  <button type="button" class="btn btn-primary">Right</button>
    -</div>
    -
    - -

    Radio

    -

    Add data-toggle="buttons-radio" for radio style toggling on btn-group.

    -
    -
    - - - -
    -
    -
    -<div class="btn-group" data-toggle="buttons-radio">
    -  <button type="button" class="btn btn-primary">Left</button>
    -  <button type="button" class="btn btn-primary">Middle</button>
    -  <button type="button" class="btn btn-primary">Right</button>
    -</div>
    -
    - - -
    - - -

    Usage

    -

    Enable buttons via JavaScript:

    -
    $('.nav-tabs').button()
    - -

    Markup

    -

    Data attributes are integral to the button plugin. Check out the example code below for the various markup types.

    - -

    Options

    -

    None

    - -

    Methods

    -

    $().button('toggle')

    -

    Toggles push state. Gives the button the appearance that it has been activated.

    -
    - Heads up! - You can enable auto toggling of a button by using the data-toggle attribute. -
    -
    <button type="button" class="btn" data-toggle="button" >…</button>
    -

    $().button('loading')

    -

    Sets button state to loading - disables button and swaps text to loading text. Loading text should be defined on the button element using the data attribute data-loading-text. -

    -
    <button type="button" class="btn" data-loading-text="loading stuff..." >...</button>
    -
    - Heads up! - Firefox persists the disabled state across page loads. A workaround for this is to use autocomplete="off". -
    -

    $().button('reset')

    -

    Resets button state - swaps text to original text.

    -

    $().button(string)

    -

    Resets button state - swaps text to any data defined text state.

    -
    <button type="button" class="btn" data-complete-text="finished!" >...</button>
    -<script>
    -  $('.btn').button('complete')
    -</script>
    -
    -
    - - - - -
    - - -

    About

    -

    Get base styles and flexible support for collapsible components like accordions and navigation.

    -

    * Requires the Transitions plugin to be included.

    - -

    Example accordion

    -

    Using the collapse plugin, we built a simple accordion style widget:

    - -
    -
    -
    - -
    -
    - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. -
    -
    -
    -
    - -
    -
    - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. -
    -
    -
    -
    - -
    -
    - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. -
    -
    -
    -
    -
    -
    -<div class="accordion" id="accordion2">
    -  <div class="accordion-group">
    -    <div class="accordion-heading">
    -      <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseOne">
    -        Collapsible Group Item #1
    -      </a>
    -    </div>
    -    <div id="collapseOne" class="accordion-body collapse in">
    -      <div class="accordion-inner">
    -        Anim pariatur cliche...
    -      </div>
    -    </div>
    -  </div>
    -  <div class="accordion-group">
    -    <div class="accordion-heading">
    -      <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseTwo">
    -        Collapsible Group Item #2
    -      </a>
    -    </div>
    -    <div id="collapseTwo" class="accordion-body collapse">
    -      <div class="accordion-inner">
    -        Anim pariatur cliche...
    -      </div>
    -    </div>
    -  </div>
    -</div>
    -...
    -
    -

    You can also use the plugin without the accordion markup. Make a button toggle the expanding and collapsing of another element.

    -
    -<button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#demo">
    -  simple collapsible
    -</button>
    -
    -<div id="demo" class="collapse in"> … </div>
    -
    - - -
    - - -

    Usage

    - -

    Via data attributes

    -

    Just add data-toggle="collapse" and a data-target to element to automatically assign control of a collapsible element. The data-target attribute accepts a css selector to apply the collapse to. Be sure to add the class collapse to the collapsible element. If you'd like it to default open, add the additional class in.

    -

    To add accordion-like group management to a collapsible control, add the data attribute data-parent="#selector". Refer to the demo to see this in action.

    - -

    Via JavaScript

    -

    Enable manually with:

    -
    $(".collapse").collapse()
    - -

    Options

    -

    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-parent="".

    - - - - - - - - - - - - - - - - - - - - - - - -
    Nametypedefaultdescription
    parentselectorfalseIf selector then all collapsible elements under the specified parent will be closed when this collapsible item is shown. (similar to traditional accordion behavior)
    togglebooleantrueToggles the collapsible element on invocation
    - - -

    Methods

    -

    .collapse(options)

    -

    Activates your content as a collapsible element. Accepts an optional options object. -

    -$('#myCollapsible').collapse({
    -  toggle: false
    -})
    -
    -

    .collapse('toggle')

    -

    Toggles a collapsible element to shown or hidden.

    -

    .collapse('show')

    -

    Shows a collapsible element.

    -

    .collapse('hide')

    -

    Hides a collapsible element.

    - -

    Events

    -

    Bootstrap's collapse class exposes a few events for hooking into collapse functionality.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    EventDescription
    showThis event fires immediately when the show instance method is called.
    shownThis event is fired when a collapse element has been made visible to the user (will wait for css transitions to complete).
    hide - This event is fired immediately when the hide method has been called. -
    hiddenThis event is fired when a collapse element has been hidden from the user (will wait for css transitions to complete).
    -
    -$('#myCollapsible').on('hidden', function () {
    -  // do something…
    -})
    -
    - - - - - - - - - -
    - - - -

    Example

    -

    A basic, easily extended plugin for quickly creating elegant typeaheads with any form text input.

    -
    - -
    -
    <input type="text" data-provide="typeahead">
    -

    You'll want to set autocomplete="off" to prevent default browser menus from appearing over the Bootstrap typeahead dropdown.

    - -
    - - -

    Usage

    - -

    Via data attributes

    -

    Add data attributes to register an element with typeahead functionality as shown in the example above.

    - -

    Via JavaScript

    -

    Call the typeahead manually with:

    -
    $('.typeahead').typeahead()
    - -

    Options

    -

    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-source="".

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Nametypedefaultdescription
    sourcearray, function[ ]The data source to query against. May be an array of strings or a function. The function is passed two arguments, the query value in the input field and the process callback. The function may be used synchronously by returning the data source directly or asynchronously via the process callback's single argument.
    itemsnumber8The max number of items to display in the dropdown.
    minLengthnumber1The minimum character length needed before triggering autocomplete suggestions
    matcherfunctioncase insensitiveThe method used to determine if a query matches an item. Accepts a single argument, the item against which to test the query. Access the current query with this.query. Return a boolean true if query is a match.
    sorterfunctionexact match,
    case sensitive,
    case insensitive
    Method used to sort autocomplete results. Accepts a single argument items and has the scope of the typeahead instance. Reference the current query with this.query.
    updaterfunctionreturns selected itemThe method used to return selected item. Accepts a single argument, the item and has the scope of the typeahead instance.
    highlighterfunctionhighlights all default matchesMethod used to highlight autocomplete results. Accepts a single argument item and has the scope of the typeahead instance. Should return html.
    - -

    Methods

    -

    .typeahead(options)

    -

    Initializes an input with a typeahead.

    -
    - - - - -
    - - -

    Example

    -

    The subnavigation on the left is a live demo of the affix plugin.

    - -
    - -

    Usage

    - -

    Via data attributes

    -

    To easily add affix behavior to any element, just add data-spy="affix" to the element you want to spy on. Then use offsets to define when to toggle the pinning of an element on and off.

    - -
    <div data-spy="affix" data-offset-top="200">...</div>
    - -
    - Heads up! - You must manage the position of a pinned element and the behavior of its immediate parent. Position is controlled by affix, affix-top, and affix-bottom. Remember to check for a potentially collapsed parent when the affix kicks in as it's removing content from the normal flow of the page. -
    - -

    Via JavaScript

    -

    Call the affix plugin via JavaScript:

    -
    $('#navbar').affix()
    - -

    Options

    -

    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-offset-top="200".

    - - - - - - - - - - - - - - - - - -
    Nametypedefaultdescription
    offsetnumber | function | object10Pixels to offset from screen when calculating position of scroll. If a single number is provided, the offset will be applied in both top and left directions. To listen for a single direction, or multiple unique offsets, just provide an object offset: { x: 10 }. Use a function when you need to dynamically provide an offset (useful for some responsive designs).
    -
    - - - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/webapp/bower_components/bootstrap/docs/scaffolding.html b/src/main/webapp/bower_components/bootstrap/docs/scaffolding.html deleted file mode 100644 index 87a9bb003..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/scaffolding.html +++ /dev/null @@ -1,602 +0,0 @@ - - - - - Scaffolding · Bootstrap - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -

    Scaffolding

    -

    Bootstrap is built on responsive 12-column grids, layouts, and components.

    -
    -
    - -
    - - -
    - -
    - - - - -
    - - -

    Requires HTML5 doctype

    -

    Bootstrap makes use of certain HTML elements and CSS properties that require the use of the HTML5 doctype. Include it at the beginning of all your projects.

    -
    -<!DOCTYPE html>
    -<html lang="en">
    -  ...
    -</html>
    -
    - -

    Typography and links

    -

    Bootstrap sets basic global display, typography, and link styles. Specifically, we:

    -
      -
    • Remove margin on the body
    • -
    • Set background-color: white; on the body
    • -
    • Use the @baseFontFamily, @baseFontSize, and @baseLineHeight attributes as our typographic base
    • -
    • Set the global link color via @linkColor and apply link underlines only on :hover
    • -
    -

    These styles can be found within scaffolding.less.

    - -

    Reset via Normalize

    -

    With Bootstrap 2, the old reset block has been dropped in favor of Normalize.css, a project by Nicolas Gallagher and Jonathan Neal that also powers the HTML5 Boilerplate. While we use much of Normalize within our reset.less, we have removed some elements specifically for Bootstrap.

    - -
    - - - - - -
    - - -

    Live grid example

    -

    The default Bootstrap grid system utilizes 12 columns, making for a 940px wide container without responsive features enabled. With the responsive CSS file added, the grid adapts to be 724px and 1170px wide depending on your viewport. Below 767px viewports, the columns become fluid and stack vertically.

    -
    -
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    -
    -
    2
    -
    3
    -
    4
    -
    -
    -
    4
    -
    5
    -
    -
    -
    9
    -
    -
    - -

    Basic grid HTML

    -

    For a simple two column layout, create a .row and add the appropriate number of .span* columns. As this is a 12-column grid, each .span* spans a number of those 12 columns, and should always add up to 12 for each row (or the number of columns in the parent).

    -
    -<div class="row">
    -  <div class="span4">...</div>
    -  <div class="span8">...</div>
    -</div>
    -
    -

    Given this example, we have .span4 and .span8, making for 12 total columns and a complete row.

    - -

    Offsetting columns

    -

    Move columns to the right using .offset* classes. Each class increases the left margin of a column by a whole column. For example, .offset4 moves .span4 over four columns.

    -
    -
    -
    4
    -
    3 offset 2
    -
    -
    -
    3 offset 1
    -
    3 offset 2
    -
    -
    -
    6 offset 3
    -
    -
    -
    -<div class="row">
    -  <div class="span4">...</div>
    -  <div class="span3 offset2">...</div>
    -</div>
    -
    - -

    Nesting columns

    -

    To nest your content with the default grid, add a new .row and set of .span* columns within an existing .span* column. Nested rows should include a set of columns that add up to the number of columns of its parent.

    -
    -
    - Level 1 column -
    -
    - Level 2 -
    -
    - Level 2 -
    -
    -
    -
    -
    -<div class="row">
    -  <div class="span9">
    -    Level 1 column
    -    <div class="row">
    -      <div class="span6">Level 2</div>
    -      <div class="span3">Level 2</div>
    -    </div>
    -  </div>
    -</div>
    -
    -
    - - - - -
    - - -

    Live fluid grid example

    -

    The fluid grid system uses percents instead of pixels for column widths. It has the same responsive capabilities as our fixed grid system, ensuring proper proportions for key screen resolutions and devices.

    -
    -
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    -
    -
    4
    -
    4
    -
    4
    -
    -
    -
    4
    -
    8
    -
    -
    -
    6
    -
    6
    -
    -
    -
    12
    -
    -
    - -

    Basic fluid grid HTML

    -

    Make any row "fluid" by changing .row to .row-fluid. The column classes stay the exact same, making it easy to flip between fixed and fluid grids.

    -
    -<div class="row-fluid">
    -  <div class="span4">...</div>
    -  <div class="span8">...</div>
    -</div>
    -
    - -

    Fluid offsetting

    -

    Operates the same way as the fixed grid system offsetting: add .offset* to any column to offset by that many columns.

    -
    -
    -
    4
    -
    4 offset 4
    -
    -
    -
    3 offset 3
    -
    3 offset 3
    -
    -
    -
    6 offset 6
    -
    -
    -
    -<div class="row-fluid">
    -  <div class="span4">...</div>
    -  <div class="span4 offset2">...</div>
    -</div>
    -
    - -

    Fluid nesting

    -

    Fluid grids utilize nesting differently: each nested level of columns should add up to 12 columns. This is because the fluid grid uses percentages, not pixels, for setting widths.

    -
    -
    - Fluid 12 -
    -
    - Fluid 6 -
    -
    - Fluid 6 -
    -
    - Fluid 6 -
    -
    -
    -
    - Fluid 6 -
    -
    -
    -
    -
    -<div class="row-fluid">
    -  <div class="span12">
    -    Fluid 12
    -    <div class="row-fluid">
    -      <div class="span6">
    -        Fluid 6
    -        <div class="row-fluid">
    -          <div class="span6">Fluid 6</div>
    -          <div class="span6">Fluid 6</div>
    -        </div>
    -      </div>
    -      <div class="span6">Fluid 6</div>
    -    </div>
    -  </div>
    -</div>
    -
    - -
    - - - - - -
    - - -

    Fixed layout

    -

    Provides a common fixed-width (and optionally responsive) layout with only <div class="container"> required.

    -
    -
    -
    -
    -<body>
    -  <div class="container">
    -    ...
    -  </div>
    -</body>
    -
    - -

    Fluid layout

    -

    Create a fluid, two-column page with <div class="container-fluid">—great for applications and docs.

    -
    -
    -
    -
    -
    -<div class="container-fluid">
    -  <div class="row-fluid">
    -    <div class="span2">
    -      <!--Sidebar content-->
    -    </div>
    -    <div class="span10">
    -      <!--Body content-->
    -    </div>
    -  </div>
    -</div>
    -
    -
    - - - - - -
    - - -

    Enabling responsive features

    -

    Turn on responsive CSS in your project by including the proper meta tag and additional stylesheet within the <head> of your document. If you've compiled Bootstrap from the Customize page, you need only include the meta tag.

    -
    -<meta name="viewport" content="width=device-width, initial-scale=1.0">
    -<link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
    -
    -

    Heads up! Bootstrap doesn't include responsive features by default at this time as not everything needs to be responsive. Instead of encouraging developers to remove this feature, we figure it best to enable it as needed.

    - -

    About responsive Bootstrap

    - Responsive devices -

    Media queries allow for custom CSS based on a number of conditions—ratios, widths, display type, etc—but usually focuses around min-width and max-width.

    -
      -
    • Modify the width of column in our grid
    • -
    • Stack elements instead of float wherever necessary
    • -
    • Resize headings and text to be more appropriate for devices
    • -
    -

    Use media queries responsibly and only as a start to your mobile audiences. For larger projects, do consider dedicated code bases and not layers of media queries.

    - -

    Supported devices

    -

    Bootstrap supports a handful of media queries in a single file to help make your projects more appropriate on different devices and screen resolutions. Here's what's included:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    LabelLayout widthColumn widthGutter width
    Large display1200px and up70px30px
    Default980px and up60px20px
    Portrait tablets768px and above42px20px
    Phones to tablets767px and belowFluid columns, no fixed widths
    Phones480px and belowFluid columns, no fixed widths
    -
    -/* Large desktop */
    -@media (min-width: 1200px) { ... }
    -
    -/* Portrait tablet to landscape and desktop */
    -@media (min-width: 768px) and (max-width: 979px) { ... }
    -
    -/* Landscape phone to portrait tablet */
    -@media (max-width: 767px) { ... }
    -
    -/* Landscape phones and down */
    -@media (max-width: 480px) { ... }
    -
    - - -

    Responsive utility classes

    -

    For faster mobile-friendly development, use these utility classes for showing and hiding content by device. Below is a table of the available classes and their effect on a given media query layout (labeled by device). They can be found in responsive.less.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ClassPhones 767px and belowTablets 979px to 768pxDesktops Default
    .visible-phoneVisible
    .visible-tabletVisible
    .visible-desktopVisible
    .hidden-phoneVisibleVisible
    .hidden-tabletVisibleVisible
    .hidden-desktopVisibleVisible
    - -

    When to use

    -

    Use on a limited basis and avoid creating entirely different versions of the same site. Instead, use them to complement each device's presentation. Responsive utilities should not be used with tables, and as such are not supported.

    - -

    Responsive utilities test case

    -

    Resize your browser or load on different devices to test the above classes.

    -

    Visible on...

    -

    Green checkmarks indicate that class is visible in your current viewport.

    -
      -
    • Phone✔ Phone
    • -
    • Tablet✔ Tablet
    • -
    • Desktop✔ Desktop
    • -
    -

    Hidden on...

    -

    Here, green checkmarks indicate that class is hidden in your current viewport.

    -
      -
    • Phone✔ Phone
    • -
    • Tablet✔ Tablet
    • -
    • Desktop✔ Desktop
    • -
    - -
    - - - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/layout.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/layout.mustache deleted file mode 100644 index 993b44620..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/layout.mustache +++ /dev/null @@ -1,151 +0,0 @@ - - - - - {{title}} - - - - - - - - - - - - - - - - - - - - - {{#production}} - - {{/production}} - - - - - - - -{{>body}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{#production}} - - - {{/production}} - - - diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/base-css.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/pages/base-css.mustache deleted file mode 100644 index 1f40f3711..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/base-css.mustache +++ /dev/null @@ -1,2102 +0,0 @@ - -
    -
    -

    {{_i}}Base CSS{{/i}}

    -

    {{_i}}Fundamental HTML elements styled and enhanced with extensible classes.{{/i}}

    -
    -
    - - -
    - - -
    - -
    - - - - -
    - - - {{! Headings }} -

    {{_i}}Headings{{/i}}

    -

    {{_i}}All HTML headings, <h1> through <h6> are available.{{/i}}

    -
    -

    h1. {{_i}}Heading 1{{/i}}

    -

    h2. {{_i}}Heading 2{{/i}}

    -

    h3. {{_i}}Heading 3{{/i}}

    -

    h4. {{_i}}Heading 4{{/i}}

    -
    h5. {{_i}}Heading 5{{/i}}
    -
    h6. {{_i}}Heading 6{{/i}}
    -
    - - {{! Body copy }} -

    {{_i}}Body copy{{/i}}

    -

    {{_i}}Bootstrap's global default font-size is 14px, with a line-height of 20px. This is applied to the <body> and all paragraphs. In addition, <p> (paragraphs) receive a bottom margin of half their line-height (10px by default).{{/i}}

    -
    -

    Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula.

    -

    Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec ullamcorper nulla non metus auctor fringilla. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla.

    -

    Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.

    -
    -
    <p>...</p>
    - - {{! Body copy .lead }} -

    {{_i}}Lead body copy{{/i}}

    -

    {{_i}}Make a paragraph stand out by adding .lead.{{/i}}

    -
    -

    Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus.

    -
    -
    <p class="lead">...</p>
    - - {{! Using LESS }} -

    {{_i}}Built with Less{{/i}}

    -

    {{_i}}The typographic scale is based on two LESS variables in variables.less: @baseFontSize and @baseLineHeight. The first is the base font-size used throughout and the second is the base line-height. We use those variables and some simple math to create the margins, paddings, and line-heights of all our type and more. Customize them and Bootstrap adapts.{{/i}}

    - - -
    - - - {{! Emphasis }} -

    {{_i}}Emphasis{{/i}}

    -

    {{_i}}Make use of HTML's default emphasis tags with lightweight styles.{{/i}}

    - -

    <small>

    -

    {{_i}}For de-emphasizing inline or blocks of text, use the small tag.{{/i}}

    -
    -

    This line of text is meant to be treated as fine print.

    -
    -
    -<p>
    -  <small>This line of text is meant to be treated as fine print.</small>
    -</p>
    -
    - -

    {{_i}}Bold{{/i}}

    -

    {{_i}}For emphasizing a snippet of text with a heavier font-weight.{{/i}}

    -
    -

    The following snippet of text is rendered as bold text.

    -
    -
    <strong>rendered as bold text</strong>
    - -

    {{_i}}Italics{{/i}}

    -

    {{_i}}For emphasizing a snippet of text with italics.{{/i}}

    -
    -

    The following snippet of text is rendered as italicized text.

    -
    -
    <em>rendered as italicized text</em>
    - -

    {{_i}}Heads up!{{/i}} {{_i}}Feel free to use <b> and <i> in HTML5. <b> is meant to highlight words or phrases without conveying additional importance while <i> is mostly for voice, technical terms, etc.{{/i}}

    - -

    {{_i}}Alignment classes{{/i}}

    -

    {{_i}}Easily realign text to components with text alignment classes.{{/i}}

    -
    -

    Left aligned text.

    -

    Center aligned text.

    -

    Right aligned text.

    -
    -
    -<p class="text-left">Left aligned text.</p>
    -<p class="text-center">Center aligned text.</p>
    -<p class="text-right">Right aligned text.</p>
    -
    - -

    {{_i}}Emphasis classes{{/i}}

    -

    {{_i}}Convey meaning through color with a handful of emphasis utility classes.{{/i}}

    -
    -

    Fusce dapibus, tellus ac cursus commodo, tortor mauris nibh.

    -

    Etiam porta sem malesuada magna mollis euismod.

    -

    Donec ullamcorper nulla non metus auctor fringilla.

    -

    Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis.

    -

    Duis mollis, est non commodo luctus, nisi erat porttitor ligula.

    -
    -
    -<p class="muted">Fusce dapibus, tellus ac cursus commodo, tortor mauris nibh.</p>
    -<p class="text-warning">Etiam porta sem malesuada magna mollis euismod.</p>
    -<p class="text-error">Donec ullamcorper nulla non metus auctor fringilla.</p>
    -<p class="text-info">Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis.</p>
    -<p class="text-success">Duis mollis, est non commodo luctus, nisi erat porttitor ligula.</p>
    -
    - - -
    - - - {{! Abbreviations }} -

    {{_i}}Abbreviations{{/i}}

    -

    {{_i}}Stylized implementation of HTML's <abbr> element for abbreviations and acronyms to show the expanded version on hover. Abbreviations with a title attribute have a light dotted bottom border and a help cursor on hover, providing additional context on hover.{{/i}}

    - -

    <abbr>

    -

    {{_i}}For expanded text on long hover of an abbreviation, include the title attribute.{{/i}}

    -
    -

    {{_i}}An abbreviation of the word attribute is attr.{{/i}}

    -
    -
    <abbr title="attribute">attr</abbr>
    - -

    <abbr class="initialism">

    -

    {{_i}}Add .initialism to an abbreviation for a slightly smaller font-size.{{/i}}

    -
    -

    {{_i}}HTML is the best thing since sliced bread.{{/i}}

    -
    -
    <abbr title="HyperText Markup Language" class="initialism">HTML</abbr>
    - - -
    - - - {{! Addresses }} -

    {{_i}}Addresses{{/i}}

    -

    {{_i}}Present contact information for the nearest ancestor or the entire body of work.{{/i}}

    - -

    <address>

    -

    {{_i}}Preserve formatting by ending all lines with <br>.{{/i}}

    -
    -
    - Twitter, Inc.
    - 795 Folsom Ave, Suite 600
    - San Francisco, CA 94107
    - P: (123) 456-7890 -
    -
    - {{_i}}Full Name{{/i}}
    - {{_i}}first.last@example.com{{/i}} -
    -
    -
    -<address>
    -  <strong>Twitter, Inc.</strong><br>
    -  795 Folsom Ave, Suite 600<br>
    -  San Francisco, CA 94107<br>
    -  <abbr title="Phone">P:</abbr> (123) 456-7890
    -</address>
    -
    -<address>
    -  <strong>{{_i}}Full Name{{/i}}</strong><br>
    -  <a href="mailto:#">{{_i}}first.last@example.com{{/i}}</a>
    -</address>
    -
    - - -
    - - - {{! Blockquotes }} -

    {{_i}}Blockquotes{{/i}}

    -

    {{_i}}For quoting blocks of content from another source within your document.{{/i}}

    - -

    {{_i}}Default blockquote{{/i}}

    -

    {{_i}}Wrap <blockquote> around any HTML as the quote. For straight quotes we recommend a <p>.{{/i}}

    -
    -
    -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

    -
    -
    -
    -<blockquote>
    -  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
    -</blockquote>
    -
    - -

    {{_i}}Blockquote options{{/i}}

    -

    {{_i}}Style and content changes for simple variations on a standard blockquote.{{/i}}

    - -

    {{_i}}Naming a source{{/i}}

    -

    {{_i}}Add <small> tag for identifying the source. Wrap the name of the source work in <cite>.{{/i}}

    -
    -
    -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

    - {{_i}}Someone famous in Source Title{{/i}} -
    -
    -
    -<blockquote>
    -  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
    -  <small>{{_i}}Someone famous <cite title="Source Title">Source Title</cite>{{/i}}</small>
    -</blockquote>
    -
    - -

    {{_i}}Alternate displays{{/i}}

    -

    {{_i}}Use .pull-right for a floated, right-aligned blockquote.{{/i}}

    -
    -
    -

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

    - {{_i}}Someone famous in Source Title{{/i}} -
    -
    -
    -<blockquote class="pull-right">
    -  ...
    -</blockquote>
    -
    - - -
    - - - -

    {{_i}}Lists{{/i}}

    - -

    {{_i}}Unordered{{/i}}

    -

    {{_i}}A list of items in which the order does not explicitly matter.{{/i}}

    -
    -
      -
    • Lorem ipsum dolor sit amet
    • -
    • Consectetur adipiscing elit
    • -
    • Integer molestie lorem at massa
    • -
    • Facilisis in pretium nisl aliquet
    • -
    • Nulla volutpat aliquam velit -
        -
      • Phasellus iaculis neque
      • -
      • Purus sodales ultricies
      • -
      • Vestibulum laoreet porttitor sem
      • -
      • Ac tristique libero volutpat at
      • -
      -
    • -
    • Faucibus porta lacus fringilla vel
    • -
    • Aenean sit amet erat nunc
    • -
    • Eget porttitor lorem
    • -
    -
    -
    -<ul>
    -  <li>...</li>
    -</ul>
    -
    - -

    {{_i}}Ordered{{/i}}

    -

    {{_i}}A list of items in which the order does explicitly matter.{{/i}}

    -
    -
      -
    1. Lorem ipsum dolor sit amet
    2. -
    3. Consectetur adipiscing elit
    4. -
    5. Integer molestie lorem at massa
    6. -
    7. Facilisis in pretium nisl aliquet
    8. -
    9. Nulla volutpat aliquam velit
    10. -
    11. Faucibus porta lacus fringilla vel
    12. -
    13. Aenean sit amet erat nunc
    14. -
    15. Eget porttitor lorem
    16. -
    -
    -
    -<ol>
    -  <li>...</li>
    -</ol>
    -
    - -

    {{_i}}Unstyled{{/i}}

    -

    {{_i}}Remove the default list-style and left padding on list items (immediate children only).{{/i}}

    -
    -
      -
    • Lorem ipsum dolor sit amet
    • -
    • Consectetur adipiscing elit
    • -
    • Integer molestie lorem at massa
    • -
    • Facilisis in pretium nisl aliquet
    • -
    • Nulla volutpat aliquam velit -
        -
      • Phasellus iaculis neque
      • -
      • Purus sodales ultricies
      • -
      • Vestibulum laoreet porttitor sem
      • -
      • Ac tristique libero volutpat at
      • -
      -
    • -
    • Faucibus porta lacus fringilla vel
    • -
    • Aenean sit amet erat nunc
    • -
    • Eget porttitor lorem
    • -
    -
    -
    -<ul class="unstyled">
    -  <li>...</li>
    -</ul>
    -
    - -

    {{_i}}Inline{{/i}}

    -

    {{_i}}Place all list items on a single line with inline-block and some light padding.{{/i}}

    -
    -
      -
    • Lorem ipsum
    • -
    • Phasellus iaculis
    • -
    • Nulla volutpat
    • -
    -
    -
    -<ul class="inline">
    -  <li>...</li>
    -</ul>
    -
    - -

    {{_i}}Description{{/i}}

    -

    {{_i}}A list of terms with their associated descriptions.{{/i}}

    -
    -
    -
    {{_i}}Description lists{{/i}}
    -
    {{_i}}A description list is perfect for defining terms.{{/i}}
    -
    Euismod
    -
    Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
    -
    Donec id elit non mi porta gravida at eget metus.
    -
    Malesuada porta
    -
    Etiam porta sem malesuada magna mollis euismod.
    -
    -
    -
    -<dl>
    -  <dt>...</dt>
    -  <dd>...</dd>
    -</dl>
    -
    - -

    {{_i}}Horizontal description{{/i}}

    -

    {{_i}}Make terms and descriptions in <dl> line up side-by-side.{{/i}}

    -
    -
    -
    {{_i}}Description lists{{/i}}
    -
    {{_i}}A description list is perfect for defining terms.{{/i}}
    -
    Euismod
    -
    Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
    -
    Donec id elit non mi porta gravida at eget metus.
    -
    Malesuada porta
    -
    Etiam porta sem malesuada magna mollis euismod.
    -
    Felis euismod semper eget lacinia
    -
    Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
    -
    -
    -
    -<dl class="dl-horizontal">
    -  <dt>...</dt>
    -  <dd>...</dd>
    -</dl>
    -
    -

    - {{_i}}Heads up!{{/i}} - {{_i}}Horizontal description lists will truncate terms that are too long to fit in the left column fix text-overflow. In narrower viewports, they will change to the default stacked layout.{{/i}} -

    -
    - - - - -
    - - -

    Inline

    -

    Wrap inline snippets of code with <code>.

    -
    - For example, <section> should be wrapped as inline. -
    -
    -{{_i}}For example, <code>&lt;section&gt;</code> should be wrapped as inline.{{/i}}
    -
    - -

    Basic block

    -

    {{_i}}Use <pre> for multiple lines of code. Be sure to escape any angle brackets in the code for proper rendering.{{/i}}

    -
    -
    <p>{{_i}}Sample text here...{{/i}}</p>
    -
    -
    -<pre>
    -  &lt;p&gt;{{_i}}Sample text here...{{/i}}&lt;/p&gt;
    -</pre>
    -
    -

    {{_i}}Heads up!{{/i}} {{_i}}Be sure to keep code within <pre> tags as close to the left as possible; it will render all tabs.{{/i}}

    -

    {{_i}}You may optionally add the .pre-scrollable class which will set a max-height of 350px and provide a y-axis scrollbar.{{/i}}

    -
    - - - - -
    - - -

    {{_i}}Default styles{{/i}}

    -

    {{_i}}For basic styling—light padding and only horizontal dividers—add the base class .table to any <table>.{{/i}}

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #{{_i}}First Name{{/i}}{{_i}}Last Name{{/i}}{{_i}}Username{{/i}}
    1MarkOtto@mdo
    2JacobThornton@fat
    3Larrythe Bird@twitter
    -
    {{! /example }} -
    -<table class="table">
    -  …
    -</table>
    -
    - - -
    - - -

    {{_i}}Optional classes{{/i}}

    -

    {{_i}}Add any of the following classes to the .table base class.{{/i}}

    - -

    {{_i}}.table-striped{{/i}}

    -

    {{_i}}Adds zebra-striping to any table row within the <tbody> via the :nth-child CSS selector (not available in IE7-8).{{/i}}

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #{{_i}}First Name{{/i}}{{_i}}Last Name{{/i}}{{_i}}Username{{/i}}
    1MarkOtto@mdo
    2JacobThornton@fat
    3Larrythe Bird@twitter
    -
    {{! /example }} -
    -<table class="table table-striped">
    -  …
    -</table>
    -
    - -

    {{_i}}.table-bordered{{/i}}

    -

    {{_i}}Add borders and rounded corners to the table.{{/i}}

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #{{_i}}First Name{{/i}}{{_i}}Last Name{{/i}}{{_i}}Username{{/i}}
    1MarkOtto@mdo
    MarkOtto@TwBootstrap
    2JacobThornton@fat
    3Larry the Bird@twitter
    -
    {{! /example }} -
    -<table class="table table-bordered">
    -  …
    -</table>
    -
    - -

    {{_i}}.table-hover{{/i}}

    -

    {{_i}}Enable a hover state on table rows within a <tbody>.{{/i}}

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #{{_i}}First Name{{/i}}{{_i}}Last Name{{/i}}{{_i}}Username{{/i}}
    1MarkOtto@mdo
    2JacobThornton@fat
    3Larry the Bird@twitter
    -
    {{! /example }} -
    -<table class="table table-hover">
    -  …
    -</table>
    -
    - -

    {{_i}}.table-condensed{{/i}}

    -

    {{_i}}Makes tables more compact by cutting cell padding in half.{{/i}}

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #{{_i}}First Name{{/i}}{{_i}}Last Name{{/i}}{{_i}}Username{{/i}}
    1MarkOtto@mdo
    2JacobThornton@fat
    3Larry the Bird@twitter
    -
    {{! /example }} -
    -<table class="table table-condensed">
    -  …
    -</table>
    -
    - - -
    - - -

    {{_i}}Optional row classes{{/i}}

    -

    {{_i}}Use contextual classes to color table rows.{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Class{{/i}}{{_i}}Description{{/i}}
    - .success - {{_i}}Indicates a successful or positive action.{{/i}}
    - .error - {{_i}}Indicates a dangerous or potentially negative action.{{/i}}
    - .warning - {{_i}}Indicates a warning that might need attention.{{/i}}
    - .info - {{_i}}Used as an alternative to the default styles.{{/i}}
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    #{{_i}}Product{{/i}}{{_i}}Payment Taken{{/i}}{{_i}}Status{{/i}}
    1TB - Monthly01/04/2012Approved
    2TB - Monthly02/04/2012Declined
    3TB - Monthly03/04/2012Pending
    4TB - Monthly04/04/2012Call in to confirm
    -
    {{! /example }} -
    -...
    -  <tr class="success">
    -    <td>1</td>
    -    <td>TB - Monthly</td>
    -    <td>01/04/2012</td>
    -    <td>Approved</td>
    -  </tr>
    -...
    -
    - - -
    - - -

    {{_i}}Supported table markup{{/i}}

    -

    {{_i}}List of supported table HTML elements and how they should be used.{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Tag{{/i}}{{_i}}Description{{/i}}
    - <table> - - {{_i}}Wrapping element for displaying data in a tabular format{{/i}} -
    - <thead> - - {{_i}}Container element for table header rows (<tr>) to label table columns{{/i}} -
    - <tbody> - - {{_i}}Container element for table rows (<tr>) in the body of the table{{/i}} -
    - <tr> - - {{_i}}Container element for a set of table cells (<td> or <th>) that appears on a single row{{/i}} -
    - <td> - - {{_i}}Default table cell{{/i}} -
    - <th> - - {{_i}}Special table cell for column (or row, depending on scope and placement) labels{{/i}} -
    - <caption> - - {{_i}}Description or summary of what the table holds, especially useful for screen readers{{/i}} -
    -
    -<table>
    -  <caption>...</caption>
    -  <thead>
    -    <tr>
    -      <th>...</th>
    -      <th>...</th>
    -    </tr>
    -  </thead>
    -  <tbody>
    -    <tr>
    -      <td>...</td>
    -      <td>...</td>
    -    </tr>
    -  </tbody>
    -</table>
    -
    - -
    - - - - -
    - - -

    {{_i}}Default styles{{/i}}

    -

    {{_i}}Individual form controls receive styling, but without any required base class on the <form> or large changes in markup. Results in stacked, left-aligned labels on top of form controls.{{/i}}

    -
    -
    - Legend - - - {{_i}}Example block-level help text here.{{/i}} - - -
    -
    {{! /example }} -
    -<form>
    -  <fieldset>
    -    <legend>{{_i}}Legend{{/i}}</legend>
    -    <label>{{_i}}Label name{{/i}}</label>
    -    <input type="text" placeholder="{{_i}}Type something…{{/i}}">
    -    <span class="help-block">Example block-level help text here.</span>
    -    <label class="checkbox">
    -      <input type="checkbox"> {{_i}}Check me out{{/i}}
    -    </label>
    -    <button type="submit" class="btn">{{_i}}Submit{{/i}}</button>
    -  </fieldset>
    -</form>
    -
    - - -
    - - -

    {{_i}}Optional layouts{{/i}}

    -

    {{_i}}Included with Bootstrap are three optional form layouts for common use cases.{{/i}}

    - -

    {{_i}}Search form{{/i}}

    -

    {{_i}}Add .form-search to the form and .search-query to the <input> for an extra-rounded text input.{{/i}}

    - {{! /example }} -
    -<form class="form-search">
    -  <input type="text" class="input-medium search-query">
    -  <button type="submit" class="btn">{{_i}}Search{{/i}}</button>
    -</form>
    -
    - -

    {{_i}}Inline form{{/i}}

    -

    {{_i}}Add .form-inline for left-aligned labels and inline-block controls for a compact layout.{{/i}}

    -
    - - - - -
    {{! /example }} -
    -<form class="form-inline">
    -  <input type="text" class="input-small" placeholder="{{_i}}Email{{/i}}">
    -  <input type="password" class="input-small" placeholder="{{_i}}Password{{/i}}">
    -  <label class="checkbox">
    -    <input type="checkbox"> {{_i}}Remember me{{/i}}
    -  </label>
    -  <button type="submit" class="btn">{{_i}}Sign in{{/i}}</button>
    -</form>
    -
    - -

    {{_i}}Horizontal form{{/i}}

    -

    {{_i}}Right align labels and float them to the left to make them appear on the same line as controls. Requires the most markup changes from a default form:{{/i}}

    -
      -
    • {{_i}}Add .form-horizontal to the form{{/i}}
    • -
    • {{_i}}Wrap labels and controls in .control-group{{/i}}
    • -
    • {{_i}}Add .control-label to the label{{/i}}
    • -
    • {{_i}}Wrap any associated controls in .controls for proper alignment{{/i}}
    • -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    - - -
    -
    -
    -
    -<form class="form-horizontal">
    -  <div class="control-group">
    -    <label class="control-label" for="inputEmail">{{_i}}Email{{/i}}</label>
    -    <div class="controls">
    -      <input type="text" id="inputEmail" placeholder="{{_i}}Email{{/i}}">
    -    </div>
    -  </div>
    -  <div class="control-group">
    -    <label class="control-label" for="inputPassword">{{_i}}Password{{/i}}</label>
    -    <div class="controls">
    -      <input type="password" id="inputPassword" placeholder="{{_i}}Password{{/i}}">
    -    </div>
    -  </div>
    -  <div class="control-group">
    -    <div class="controls">
    -      <label class="checkbox">
    -        <input type="checkbox"> {{_i}}Remember me{{/i}}
    -      </label>
    -      <button type="submit" class="btn">{{_i}}Sign in{{/i}}</button>
    -    </div>
    -  </div>
    -</form>
    -
    - - -
    - - -

    {{_i}}Supported form controls{{/i}}

    -

    {{_i}}Examples of standard form controls supported in an example form layout.{{/i}}

    - -

    {{_i}}Inputs{{/i}}

    -

    {{_i}}Most common form control, text-based input fields. Includes support for all HTML5 types: text, password, datetime, datetime-local, date, month, time, week, number, email, url, search, tel, and color.{{/i}}

    -

    {{_i}}Requires the use of a specified type at all times.{{/i}}

    -
    - -
    -
    -<input type="text" placeholder="Text input">
    -
    - -

    {{_i}}Textarea{{/i}}

    -

    {{_i}}Form control which supports multiple lines of text. Change rows attribute as necessary.{{/i}}

    -
    - -
    -
    -<textarea rows="3"></textarea>
    -
    - -

    {{_i}}Checkboxes and radios{{/i}}

    -

    {{_i}}Checkboxes are for selecting one or several options in a list while radios are for selecting one option from many.{{/i}}

    -

    {{_i}}Default (stacked){{/i}}

    -
    - -
    - - -
    -
    -<label class="checkbox">
    -  <input type="checkbox" value="">
    -  {{_i}}Option one is this and that—be sure to include why it's great{{/i}}
    -</label>
    -
    -<label class="radio">
    -  <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
    -  {{_i}}Option one is this and that—be sure to include why it's great{{/i}}
    -</label>
    -<label class="radio">
    -  <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2">
    -  {{_i}}Option two can be something else and selecting it will deselect option one{{/i}}
    -</label>
    -
    - -

    {{_i}}Inline checkboxes{{/i}}

    -

    {{_i}}Add the .inline class to a series of checkboxes or radios for controls appear on the same line.{{/i}}

    -
    - - - -
    -
    -<label class="checkbox inline">
    -  <input type="checkbox" id="inlineCheckbox1" value="option1"> 1
    -</label>
    -<label class="checkbox inline">
    -  <input type="checkbox" id="inlineCheckbox2" value="option2"> 2
    -</label>
    -<label class="checkbox inline">
    -  <input type="checkbox" id="inlineCheckbox3" value="option3"> 3
    -</label>
    -
    - -

    {{_i}}Selects{{/i}}

    -

    {{_i}}Use the default option or specify a multiple="multiple" to show multiple options at once.{{/i}}

    -
    - -
    - -
    -
    -<select>
    -  <option>1</option>
    -  <option>2</option>
    -  <option>3</option>
    -  <option>4</option>
    -  <option>5</option>
    -</select>
    -
    -<select multiple="multiple">
    -  <option>1</option>
    -  <option>2</option>
    -  <option>3</option>
    -  <option>4</option>
    -  <option>5</option>
    -</select>
    -
    - - -
    - - -

    {{_i}}Extending form controls{{/i}}

    -

    {{_i}}Adding on top of existing browser controls, Bootstrap includes other useful form components.{{/i}}

    - -

    {{_i}}Prepended and appended inputs{{/i}}

    -

    {{_i}}Add text or buttons before or after any text-based input. Do note that select elements are not supported here.{{/i}}

    - -

    {{_i}}Default options{{/i}}

    -

    {{_i}}Wrap an .add-on and an input with one of two classes to prepend or append text to an input.{{/i}}

    -
    -
    - @ - -
    -
    -
    - - .00 -
    -
    -
    -<div class="input-prepend">
    -  <span class="add-on">@</span>
    -  <input class="span2" id="prependedInput" type="text" placeholder="{{_i}}Username{{/i}}">
    -</div>
    -<div class="input-append">
    -  <input class="span2" id="appendedInput" type="text">
    -  <span class="add-on">.00</span>
    -</div>
    -
    - -

    {{_i}}Combined{{/i}}

    -

    {{_i}}Use both classes and two instances of .add-on to prepend and append an input.{{/i}}

    -
    -
    - $ - - .00 -
    -
    -
    -<div class="input-prepend input-append">
    -  <span class="add-on">$</span>
    -  <input class="span2" id="appendedPrependedInput" type="text">
    -  <span class="add-on">.00</span>
    -</div>
    -
    - -

    {{_i}}Buttons instead of text{{/i}}

    -

    {{_i}}Instead of a <span> with text, use a .btn to attach a button (or two) to an input.{{/i}}

    -
    -
    - - -
    -
    -
    -<div class="input-append">
    -  <input class="span2" id="appendedInputButton" type="text">
    -  <button class="btn" type="button">Go!</button>
    -</div>
    -
    -
    -
    - - - -
    -
    -
    -<div class="input-append">
    -  <input class="span2" id="appendedInputButtons" type="text">
    -  <button class="btn" type="button">Search</button>
    -  <button class="btn" type="button">Options</button>
    -</div>
    -
    - -

    {{_i}}Button dropdowns{{/i}}

    -

    {{_i}}{{/i}}

    -
    - -
    -
    -<div class="input-append">
    -  <input class="span2" id="appendedDropdownButton" type="text">
    -  <div class="btn-group">
    -    <button class="btn dropdown-toggle" data-toggle="dropdown">
    -      {{_i}}Action{{/i}}
    -      <span class="caret"></span>
    -    </button>
    -    <ul class="dropdown-menu">
    -      ...
    -    </ul>
    -  </div>
    -</div>
    -
    - -
    - -
    -
    -<div class="input-prepend">
    -  <div class="btn-group">
    -    <button class="btn dropdown-toggle" data-toggle="dropdown">
    -      {{_i}}Action{{/i}}
    -      <span class="caret"></span>
    -    </button>
    -    <ul class="dropdown-menu">
    -      ...
    -    </ul>
    -  </div>
    -  <input class="span2" id="prependedDropdownButton" type="text">
    -</div>
    -
    - -
    - -
    -
    -<div class="input-prepend input-append">
    -  <div class="btn-group">
    -    <button class="btn dropdown-toggle" data-toggle="dropdown">
    -      {{_i}}Action{{/i}}
    -      <span class="caret"></span>
    -    </button>
    -    <ul class="dropdown-menu">
    -      ...
    -    </ul>
    -  </div>
    -  <input class="span2" id="appendedPrependedDropdownButton" type="text">
    -  <div class="btn-group">
    -    <button class="btn dropdown-toggle" data-toggle="dropdown">
    -      {{_i}}Action{{/i}}
    -      <span class="caret"></span>
    -    </button>
    -    <ul class="dropdown-menu">
    -      ...
    -    </ul>
    -  </div>
    -</div>
    -
    - -

    {{_i}}Segmented dropdown groups{{/i}}

    -
    - - -
    -
    -<form>
    -  <div class="input-prepend">
    -    <div class="btn-group">...</div>
    -    <input type="text">
    -  </div>
    -  <div class="input-append">
    -    <input type="text">
    -    <div class="btn-group">...</div>
    -  </div>
    -</form>
    -
    - -

    {{_i}}Search form{{/i}}

    - {{! /example }} -
    -<form class="form-search">
    -  <div class="input-append">
    -    <input type="text" class="span2 search-query">
    -    <button type="submit" class="btn">{{_i}}Search{{/i}}</button>
    -  </div>
    -  <div class="input-prepend">
    -    <button type="submit" class="btn">{{_i}}Search{{/i}}</button>
    -    <input type="text" class="span2 search-query">
    -  </div>
    -</form>
    -
    - -

    {{_i}}Control sizing{{/i}}

    -

    {{_i}}Use relative sizing classes like .input-large or match your inputs to the grid column sizes using .span* classes.{{/i}}

    - -

    {{_i}}Block level inputs{{/i}}

    -

    {{_i}}Make any <input> or <textarea> element behave like a block level element.{{/i}}

    -
    -
    - -
    -
    -
    -<input class="input-block-level" type="text" placeholder=".input-block-level">
    -
    - -

    {{_i}}Relative sizing{{/i}}

    -
    -
    - - - - - - -
    -
    -
    -<input class="input-mini" type="text" placeholder=".input-mini">
    -<input class="input-small" type="text" placeholder=".input-small">
    -<input class="input-medium" type="text" placeholder=".input-medium">
    -<input class="input-large" type="text" placeholder=".input-large">
    -<input class="input-xlarge" type="text" placeholder=".input-xlarge">
    -<input class="input-xxlarge" type="text" placeholder=".input-xxlarge">
    -
    -

    - {{_i}}Heads up!{{/i}} In future versions, we'll be altering the use of these relative input classes to match our button sizes. For example, .input-large will increase the padding and font-size of an input. -

    - -

    {{_i}}Grid sizing{{/i}}

    -

    {{_i}}Use .span1 to .span12 for inputs that match the same sizes of the grid columns.{{/i}}

    -
    -
    - - - - - - -
    -
    -
    -<input class="span1" type="text" placeholder=".span1">
    -<input class="span2" type="text" placeholder=".span2">
    -<input class="span3" type="text" placeholder=".span3">
    -<select class="span1">
    -  ...
    -</select>
    -<select class="span2">
    -  ...
    -</select>
    -<select class="span3">
    -  ...
    -</select>
    -
    - -

    {{_i}}For multiple grid inputs per line, use the .controls-row modifier class for proper spacing. It floats the inputs to collapse white-space, sets the proper margins, and clears the float.{{/i}}

    -
    -
    - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -<div class="controls">
    -  <input class="span5" type="text" placeholder=".span5">
    -</div>
    -<div class="controls controls-row">
    -  <input class="span4" type="text" placeholder=".span4">
    -  <input class="span1" type="text" placeholder=".span1">
    -</div>
    -...
    -
    - -

    {{_i}}Uneditable inputs{{/i}}

    -

    {{_i}}Present data in a form that's not editable without using actual form markup.{{/i}}

    -
    - Some value here -
    -
    -<span class="input-xlarge uneditable-input">Some value here</span>
    -
    - -

    {{_i}}Form actions{{/i}}

    -

    {{_i}}End a form with a group of actions (buttons). When placed within a .form-actions, the buttons will automatically indent to line up with the form controls.{{/i}}

    -
    -
    - - -
    -
    -
    -<div class="form-actions">
    -  <button type="submit" class="btn btn-primary">{{_i}}Save changes{{/i}}</button>
    -  <button type="button" class="btn">{{_i}}Cancel{{/i}}</button>
    -</div>
    -
    - -

    {{_i}}Help text{{/i}}

    -

    {{_i}}Inline and block level support for help text that appears around form controls.{{/i}}

    -

    {{_i}}Inline help{{/i}}

    -
    - Inline help text -
    -
    -<input type="text"><span class="help-inline">Inline help text</span>
    -
    - -

    {{_i}}Block help{{/i}}

    -
    - - A longer block of help text that breaks onto a new line and may extend beyond one line. -
    -
    -<input type="text"><span class="help-block">A longer block of help text that breaks onto a new line and may extend beyond one line.</span>
    -
    - - -
    - - -

    {{_i}}Form control states{{/i}}

    -

    {{_i}}Provide feedback to users or visitors with basic feedback states on form controls and labels.{{/i}}

    - -

    {{_i}}Input focus{{/i}}

    -

    {{_i}}We remove the default outline styles on some form controls and apply a box-shadow in its place for :focus.{{/i}}

    -
    - -
    -
    -<input class="input-xlarge" id="focusedInput" type="text" value="{{_i}}This is focused...{{/i}}">
    -
    - -

    {{_i}}Invalid inputs{{/i}}

    -

    {{_i}}Style inputs via default browser functionality with :invalid. Specify a type, add the required attribute if the field is not optional, and (if applicable) specify a pattern.{{/i}}

    -

    {{_i}}This is not available in versions of Internet Explorer 7-9 due to lack of support for CSS pseudo selectors.{{/i}}

    -
    - -
    -
    -<input class="span3" type="email" required>
    -
    - -

    {{_i}}Disabled inputs{{/i}}

    -

    {{_i}}Add the disabled attribute on an input to prevent user input and trigger a slightly different look.{{/i}}

    -
    - -
    -
    -<input class="input-xlarge" id="disabledInput" type="text" placeholder="{{_i}}Disabled input here...{{/i}}" disabled>
    -
    - -

    {{_i}}Validation states{{/i}}

    -

    {{_i}}Bootstrap includes validation styles for error, warning, info, and success messages. To use, add the appropriate class to the surrounding .control-group.{{/i}}

    - -
    -
    - -
    - - {{_i}}Something may have gone wrong{{/i}} -
    -
    -
    - -
    - - {{_i}}Please correct the error{{/i}} -
    -
    -
    - -
    - - {{_i}}Username is taken{{/i}} -
    -
    -
    - -
    - - {{_i}}Woohoo!{{/i}} -
    -
    -
    -
    -<div class="control-group warning">
    -  <label class="control-label" for="inputWarning">{{_i}}Input with warning{{/i}}</label>
    -  <div class="controls">
    -    <input type="text" id="inputWarning">
    -    <span class="help-inline">{{_i}}Something may have gone wrong{{/i}}</span>
    -  </div>
    -</div>
    -
    -<div class="control-group error">
    -  <label class="control-label" for="inputError">{{_i}}Input with error{{/i}}</label>
    -  <div class="controls">
    -    <input type="text" id="inputError">
    -    <span class="help-inline">{{_i}}Please correct the error{{/i}}</span>
    -  </div>
    -</div>
    -
    -<div class="control-group info">
    -  <label class="control-label" for="inputInfo">{{_i}}Input with info{{/i}}</label>
    -  <div class="controls">
    -    <input type="text" id="inputInfo">
    -    <span class="help-inline">{{_i}}Username is already taken{{/i}}</span>
    -  </div>
    -</div>
    -
    -<div class="control-group success">
    -  <label class="control-label" for="inputSuccess">{{_i}}Input with success{{/i}}</label>
    -  <div class="controls">
    -    <input type="text" id="inputSuccess">
    -    <span class="help-inline">{{_i}}Woohoo!{{/i}}</span>
    -  </div>
    -</div>
    -
    - -
    - - - - -
    - - -

    Default buttons

    -

    {{_i}}Button styles can be applied to anything with the .btn class applied. However, typically you'll want to apply these to only <a> and <button> elements for the best rendering.{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Button{{/i}}{{_i}}class=""{{/i}}{{_i}}Description{{/i}}
    btn{{_i}}Standard gray button with gradient{{/i}}
    btn btn-primary{{_i}}Provides extra visual weight and identifies the primary action in a set of buttons{{/i}}
    btn btn-info{{_i}}Used as an alternative to the default styles{{/i}}
    btn btn-success{{_i}}Indicates a successful or positive action{{/i}}
    btn btn-warning{{_i}}Indicates caution should be taken with this action{{/i}}
    btn btn-danger{{_i}}Indicates a dangerous or potentially negative action{{/i}}
    btn btn-inverse{{_i}}Alternate dark gray button, not tied to a semantic action or use{{/i}}
    btn btn-link{{_i}}Deemphasize a button by making it look like a link while maintaining button behavior{{/i}}
    - -

    {{_i}}Cross browser compatibility{{/i}}

    -

    {{_i}}IE9 doesn't crop background gradients on rounded corners, so we remove it. Related, IE9 jankifies disabled button elements, rendering text gray with a nasty text-shadow that we cannot fix.{{/i}}

    - - -

    {{_i}}Button sizes{{/i}}

    -

    {{_i}}Fancy larger or smaller buttons? Add .btn-large, .btn-small, or .btn-mini for additional sizes.{{/i}}

    -
    -

    - - -

    -

    - - -

    -

    - - -

    -

    - - -

    -
    -
    -<p>
    -  <button class="btn btn-large btn-primary" type="button">{{_i}}Large button{{/i}}</button>
    -  <button class="btn btn-large" type="button">{{_i}}Large button{{/i}}</button>
    -</p>
    -<p>
    -  <button class="btn btn-primary" type="button">{{_i}}Default button{{/i}}</button>
    -  <button class="btn" type="button">{{_i}}Default button{{/i}}</button>
    -</p>
    -<p>
    -  <button class="btn btn-small btn-primary" type="button">{{_i}}Small button{{/i}}</button>
    -  <button class="btn btn-small" type="button">{{_i}}Small button{{/i}}</button>
    -</p>
    -<p>
    -  <button class="btn btn-mini btn-primary" type="button">{{_i}}Mini button{{/i}}</button>
    -  <button class="btn btn-mini" type="button">{{_i}}Mini button{{/i}}</button>
    -</p>
    -
    -

    {{_i}}Create block level buttons—those that span the full width of a parent— by adding .btn-block.{{/i}}

    -
    -
    - - -
    -
    -
    -<button class="btn btn-large btn-block btn-primary" type="button">{{_i}}Block level button{{/i}}</button>
    -<button class="btn btn-large btn-block" type="button">{{_i}}Block level button{{/i}}</button>
    -
    - - -

    {{_i}}Disabled state{{/i}}

    -

    {{_i}}Make buttons look unclickable by fading them back 50%.{{/i}}

    - -

    Anchor element

    -

    {{_i}}Add the .disabled class to <a> buttons.{{/i}}

    -

    - {{_i}}Primary link{{/i}} - {{_i}}Link{{/i}} -

    -
    -<a href="#" class="btn btn-large btn-primary disabled">{{_i}}Primary link{{/i}}</a>
    -<a href="#" class="btn btn-large disabled">{{_i}}Link{{/i}}</a>
    -
    -

    - {{_i}}Heads up!{{/i}} - {{_i}}We use .disabled as a utility class here, similar to the common .active class, so no prefix is required. Also, this class is only for aesthetic; you must use custom JavaScript to disable links here.{{/i}} -

    - -

    Button element

    -

    {{_i}}Add the disabled attribute to <button> buttons.{{/i}}

    -

    - - -

    -
    -<button type="button" class="btn btn-large btn-primary disabled" disabled="disabled">{{_i}}Primary button{{/i}}</button>
    -<button type="button" class="btn btn-large" disabled>{{_i}}Button{{/i}}</button>
    -
    - - -

    {{_i}}One class, multiple tags{{/i}}

    -

    {{_i}}Use the .btn class on an <a>, <button>, or <input> element.{{/i}}

    -
    - {{_i}}Link{{/i}} - - - -
    -
    -<a class="btn" href="">{{_i}}Link{{/i}}</a>
    -<button class="btn" type="submit">{{_i}}Button{{/i}}</button>
    -<input class="btn" type="button" value="{{_i}}Input{{/i}}">
    -<input class="btn" type="submit" value="{{_i}}Submit{{/i}}">
    -
    -

    {{_i}}As a best practice, try to match the element for your context to ensure matching cross-browser rendering. If you have an input, use an <input type="submit"> for your button.{{/i}}

    - -
    - - - - -
    - - -

    {{_i}}Add classes to an <img> element to easily style images in any project.{{/i}}

    -
    - - - -
    -
    -<img src="..." class="img-rounded">
    -<img src="..." class="img-circle">
    -<img src="..." class="img-polaroid">
    -
    -

    {{_i}}Heads up!{{/i}} {{_i}}.img-rounded and .img-circle do not work in IE7-8 due to lack of border-radius support.{{/i}}

    - - -
    - - - - -
    - - -

    {{_i}}Icon glyphs{{/i}}

    -

    {{_i}}140 icons in sprite form, available in dark gray (default) and white, provided by Glyphicons.{{/i}}

    -
      -
    • icon-glass
    • -
    • icon-music
    • -
    • icon-search
    • -
    • icon-envelope
    • -
    • icon-heart
    • -
    • icon-star
    • -
    • icon-star-empty
    • -
    • icon-user
    • -
    • icon-film
    • -
    • icon-th-large
    • -
    • icon-th
    • -
    • icon-th-list
    • -
    • icon-ok
    • -
    • icon-remove
    • -
    • icon-zoom-in
    • -
    • icon-zoom-out
    • -
    • icon-off
    • -
    • icon-signal
    • -
    • icon-cog
    • -
    • icon-trash
    • -
    • icon-home
    • -
    • icon-file
    • -
    • icon-time
    • -
    • icon-road
    • -
    • icon-download-alt
    • -
    • icon-download
    • -
    • icon-upload
    • -
    • icon-inbox
    • - -
    • icon-play-circle
    • -
    • icon-repeat
    • -
    • icon-refresh
    • -
    • icon-list-alt
    • -
    • icon-lock
    • -
    • icon-flag
    • -
    • icon-headphones
    • -
    • icon-volume-off
    • -
    • icon-volume-down
    • -
    • icon-volume-up
    • -
    • icon-qrcode
    • -
    • icon-barcode
    • -
    • icon-tag
    • -
    • icon-tags
    • -
    • icon-book
    • -
    • icon-bookmark
    • -
    • icon-print
    • -
    • icon-camera
    • -
    • icon-font
    • -
    • icon-bold
    • -
    • icon-italic
    • -
    • icon-text-height
    • -
    • icon-text-width
    • -
    • icon-align-left
    • -
    • icon-align-center
    • -
    • icon-align-right
    • -
    • icon-align-justify
    • -
    • icon-list
    • - -
    • icon-indent-left
    • -
    • icon-indent-right
    • -
    • icon-facetime-video
    • -
    • icon-picture
    • -
    • icon-pencil
    • -
    • icon-map-marker
    • -
    • icon-adjust
    • -
    • icon-tint
    • -
    • icon-edit
    • -
    • icon-share
    • -
    • icon-check
    • -
    • icon-move
    • -
    • icon-step-backward
    • -
    • icon-fast-backward
    • -
    • icon-backward
    • -
    • icon-play
    • -
    • icon-pause
    • -
    • icon-stop
    • -
    • icon-forward
    • -
    • icon-fast-forward
    • -
    • icon-step-forward
    • -
    • icon-eject
    • -
    • icon-chevron-left
    • -
    • icon-chevron-right
    • -
    • icon-plus-sign
    • -
    • icon-minus-sign
    • -
    • icon-remove-sign
    • -
    • icon-ok-sign
    • - -
    • icon-question-sign
    • -
    • icon-info-sign
    • -
    • icon-screenshot
    • -
    • icon-remove-circle
    • -
    • icon-ok-circle
    • -
    • icon-ban-circle
    • -
    • icon-arrow-left
    • -
    • icon-arrow-right
    • -
    • icon-arrow-up
    • -
    • icon-arrow-down
    • -
    • icon-share-alt
    • -
    • icon-resize-full
    • -
    • icon-resize-small
    • -
    • icon-plus
    • -
    • icon-minus
    • -
    • icon-asterisk
    • -
    • icon-exclamation-sign
    • -
    • icon-gift
    • -
    • icon-leaf
    • -
    • icon-fire
    • -
    • icon-eye-open
    • -
    • icon-eye-close
    • -
    • icon-warning-sign
    • -
    • icon-plane
    • -
    • icon-calendar
    • -
    • icon-random
    • -
    • icon-comment
    • -
    • icon-magnet
    • - -
    • icon-chevron-up
    • -
    • icon-chevron-down
    • -
    • icon-retweet
    • -
    • icon-shopping-cart
    • -
    • icon-folder-close
    • -
    • icon-folder-open
    • -
    • icon-resize-vertical
    • -
    • icon-resize-horizontal
    • -
    • icon-hdd
    • -
    • icon-bullhorn
    • -
    • icon-bell
    • -
    • icon-certificate
    • -
    • icon-thumbs-up
    • -
    • icon-thumbs-down
    • -
    • icon-hand-right
    • -
    • icon-hand-left
    • -
    • icon-hand-up
    • -
    • icon-hand-down
    • -
    • icon-circle-arrow-right
    • -
    • icon-circle-arrow-left
    • -
    • icon-circle-arrow-up
    • -
    • icon-circle-arrow-down
    • -
    • icon-globe
    • -
    • icon-wrench
    • -
    • icon-tasks
    • -
    • icon-filter
    • -
    • icon-briefcase
    • -
    • icon-fullscreen
    • -
    - -

    Glyphicons attribution

    -

    {{_i}}Glyphicons Halflings are normally not available for free, but an arrangement between Bootstrap and the Glyphicons creators have made this possible at no cost to you as developers. As a thank you, we ask you to include an optional link back to Glyphicons whenever practical.{{/i}}

    - - -
    - - -

    {{_i}}How to use{{/i}}

    -

    {{_i}}All icons require an <i> tag with a unique class, prefixed with icon-. To use, place the following code just about anywhere:{{/i}}

    -
    -<i class="icon-search"></i>
    -
    -

    {{_i}}There are also styles available for inverted (white) icons, made ready with one extra class. We will specifically enforce this class on hover and active states for nav and dropdown links.{{/i}}

    -
    -<i class="icon-search icon-white"></i>
    -
    -

    - {{_i}}Heads up!{{/i}} - {{_i}}When using beside strings of text, as in buttons or nav links, be sure to leave a space after the <i> tag for proper spacing.{{/i}} -

    - - -
    - - -

    {{_i}}Icon examples{{/i}}

    -

    {{_i}}Use them in buttons, button groups for a toolbar, navigation, or prepended form inputs.{{/i}}

    - -

    {{_i}}Buttons{{/i}}

    - -
    {{_i}}Button group in a button toolbar{{/i}}
    -
    -
    -
    - - - - -
    -
    -
    {{! /bs-docs-example }} -
    -<div class="btn-toolbar">
    -  <div class="btn-group">
    -    <a class="btn" href="#"><i class="icon-align-left"></i></a>
    -    <a class="btn" href="#"><i class="icon-align-center"></i></a>
    -    <a class="btn" href="#"><i class="icon-align-right"></i></a>
    -    <a class="btn" href="#"><i class="icon-align-justify"></i></a>
    -  </div>
    -</div>
    -
    - -
    {{_i}}Dropdown in a button group{{/i}}
    - {{! /bs-docs-example }} -
    -<div class="btn-group">
    -  <a class="btn btn-primary" href="#"><i class="icon-user icon-white"></i> {{_i}}User{{/i}}</a>
    -  <a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#"><span class="caret"></span></a>
    -  <ul class="dropdown-menu">
    -    <li><a href="#"><i class="icon-pencil"></i> {{_i}}Edit{{/i}}</a></li>
    -    <li><a href="#"><i class="icon-trash"></i> {{_i}}Delete{{/i}}</a></li>
    -    <li><a href="#"><i class="icon-ban-circle"></i> {{_i}}Ban{{/i}}</a></li>
    -    <li class="divider"></li>
    -    <li><a href="#"><i class="i"></i> {{_i}}Make admin{{/i}}</a></li>
    -  </ul>
    -</div>
    -
    - -
    {{_i}}Button sizes{{/i}}
    - {{! /bs-docs-example }} -
    -<a class="btn btn-large" href="#"><i class="icon-star"></i> Star</a>
    -<a class="btn btn-small" href="#"><i class="icon-star"></i> Star</a>
    -<a class="btn btn-mini" href="#"><i class="icon-star"></i> Star</a>
    -
    - -

    {{_i}}Navigation{{/i}}

    - {{! /bs-docs-example }} -
    -<ul class="nav nav-list">
    -  <li class="active"><a href="#"><i class="icon-home icon-white"></i> {{_i}}Home{{/i}}</a></li>
    -  <li><a href="#"><i class="icon-book"></i> {{_i}}Library{{/i}}</a></li>
    -  <li><a href="#"><i class="icon-pencil"></i> {{_i}}Applications{{/i}}</a></li>
    -  <li><a href="#"><i class="i"></i> {{_i}}Misc{{/i}}</a></li>
    -</ul>
    -
    - -

    {{_i}}Form fields{{/i}}

    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -<div class="control-group">
    -  <label class="control-label" for="inputIcon">{{_i}}Email address{{/i}}</label>
    -  <div class="controls">
    -    <div class="input-prepend">
    -      <span class="add-on"><i class="icon-envelope"></i></span>
    -      <input class="span2" id="inputIcon" type="text">
    -    </div>
    -  </div>
    -</div>
    -
    - -
    - - - -
    {{! /span9 }} -
    {{! row}} - -
    {{! /.container }} diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/components.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/pages/components.mustache deleted file mode 100644 index 6d3ff9bee..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/components.mustache +++ /dev/null @@ -1,2505 +0,0 @@ - -
    -
    -

    {{_i}}Components{{/i}}

    -

    {{_i}}Dozens of reusable components built to provide navigation, alerts, popovers, and more.{{/i}}

    -
    -
    - - -
    - - -
    - -
    - - - - - - - - - - -
    - - -

    {{_i}}Examples{{/i}}

    -

    {{_i}}Two basic options, along with two more specific variations.{{/i}}

    - -

    {{_i}}Single button group{{/i}}

    -

    {{_i}}Wrap a series of buttons with .btn in .btn-group.{{/i}}

    -
    -
    - - - -
    -
    -
    -<div class="btn-group">
    -  <button class="btn">Left</button>
    -  <button class="btn">Middle</button>
    -  <button class="btn">Right</button>
    -</div>
    -
    - -

    {{_i}}Multiple button groups{{/i}}

    -

    {{_i}}Combine sets of <div class="btn-group"> into a <div class="btn-toolbar"> for more complex components.{{/i}}

    -
    -
    -
    - - - - -
    -
    - - - -
    -
    - -
    -
    -
    -
    -<div class="btn-toolbar">
    -  <div class="btn-group">
    -    ...
    -  </div>
    -</div>
    -
    - -

    {{_i}}Vertical button groups{{/i}}

    -

    {{_i}}Make a set of buttons appear vertically stacked rather than horizontally.{{/i}}

    -
    -
    - - - - -
    -
    -
    -<div class="btn-group btn-group-vertical">
    -  ...
    -</div>
    -
    - - -
    - - -

    {{_i}}Checkbox and radio flavors{{/i}}

    -

    {{_i}}Button groups can also function as radios, where only one button may be active, or checkboxes, where any number of buttons may be active. View the JavaScript docs for that.{{/i}}

    - -

    {{_i}}Dropdowns in button groups{{/i}}

    -

    {{_i}}Heads up!{{/i}} {{_i}}Buttons with dropdowns must be individually wrapped in their own .btn-group within a .btn-toolbar for proper rendering.{{/i}}

    -
    - - - - -
    - - - -

    {{_i}}Overview and examples{{/i}}

    -

    {{_i}}Use any button to trigger a dropdown menu by placing it within a .btn-group and providing the proper menu markup.{{/i}}

    - {{! /example }} -
    -<div class="btn-group">
    -  <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
    -    {{_i}}Action{{/i}}
    -    <span class="caret"></span>
    -  </a>
    -  <ul class="dropdown-menu">
    -    <!-- {{_i}}dropdown menu links{{/i}} -->
    -  </ul>
    -</div>
    -
    - -

    {{_i}}Works with all button sizes{{/i}}

    -

    {{_i}}Button dropdowns work at any size: .btn-large, .btn-small, or .btn-mini.{{/i}}

    - {{! /example }} - -

    {{_i}}Requires JavaScript{{/i}}

    -

    {{_i}}Button dropdowns require the Bootstrap dropdown plugin to function.{{/i}}

    -

    {{_i}}In some cases—like mobile—dropdown menus will extend outside the viewport. You need to resolve the alignment manually or with custom JavaScript.{{/i}}

    - - -
    - - -

    {{_i}}Split button dropdowns{{/i}}

    -

    {{_i}}Building on the button group styles and markup, we can easily create a split button. Split buttons feature a standard action on the left and a dropdown toggle on the right with contextual links.{{/i}}

    - {{! /example }} -
    -<div class="btn-group">
    -  <button class="btn">{{_i}}Action{{/i}}</button>
    -  <button class="btn dropdown-toggle" data-toggle="dropdown">
    -    <span class="caret"></span>
    -  </button>
    -  <ul class="dropdown-menu">
    -    <!-- {{_i}}dropdown menu links{{/i}} -->
    -  </ul>
    -</div>
    -
    - -

    {{_i}}Sizes{{/i}}

    -

    {{_i}}Utilize the extra button classes .btn-mini, .btn-small, or .btn-large for sizing.{{/i}}

    - {{! /example }} -
    -<div class="btn-group">
    -  <button class="btn btn-mini">{{_i}}Action{{/i}}</button>
    -  <button class="btn btn-mini dropdown-toggle" data-toggle="dropdown">
    -    <span class="caret"></span>
    -  </button>
    -  <ul class="dropdown-menu">
    -    <!-- {{_i}}dropdown menu links{{/i}} -->
    -  </ul>
    -</div>
    -
    - -

    {{_i}}Dropup menus{{/i}}

    -

    {{_i}}Dropdown menus can also be toggled from the bottom up by adding a single class to the immediate parent of .dropdown-menu. It will flip the direction of the .caret and reposition the menu itself to move from the bottom up instead of top down.{{/i}}

    - {{! /example }} -
    -<div class="btn-group dropup">
    -  <button class="btn">{{_i}}Dropup{{/i}}</button>
    -  <button class="btn dropdown-toggle" data-toggle="dropdown">
    -    <span class="caret"></span>
    -  </button>
    -  <ul class="dropdown-menu">
    -    <!-- {{_i}}dropdown menu links{{/i}} -->
    -  </ul>
    -</div>
    -
    - -
    - - - - - - - - - - - - - - - - - - - -
    - - -

    {{_i}}Standard pagination{{/i}}

    -

    {{_i}}Simple pagination inspired by Rdio, great for apps and search results. The large block is hard to miss, easily scalable, and provides large click areas.{{/i}}

    -
    - -
    -
    -<div class="pagination">
    -  <ul>
    -    <li><a href="#">Prev</a></li>
    -    <li><a href="#">1</a></li>
    -    <li><a href="#">2</a></li>
    -    <li><a href="#">3</a></li>
    -    <li><a href="#">4</a></li>
    -    <li><a href="#">5</a></li>
    -    <li><a href="#">Next</a></li>
    -  </ul>
    -</div>
    -
    - - -
    - - -

    {{_i}}Options{{/i}}

    - -

    {{_i}}Disabled and active states{{/i}}

    -

    {{_i}}Links are customizable for different circumstances. Use .disabled for unclickable links and .active to indicate the current page.{{/i}}

    -
    - -
    -
    -<div class="pagination">
    -  <ul>
    -    <li class="disabled"><a href="#">&laquo;</a></li>
    -    <li class="active"><a href="#">1</a></li>
    -    ...
    -  </ul>
    -</div>
    -
    -

    {{_i}}You can optionally swap out active or disabled anchors for spans to remove click functionality while retaining intended styles.{{/i}}

    -
    -<div class="pagination">
    -  <ul>
    -    <li class="disabled"><span>&laquo;</span></li>
    -    <li class="active"><span>1</span></li>
    -    ...
    -  </ul>
    -</div>
    -
    - -

    {{_i}}Sizes{{/i}}

    -

    {{_i}}Fancy larger or smaller pagination? Add .pagination-large, .pagination-small, or .pagination-mini for additional sizes.{{/i}}

    -
    - - - - -
    -
    -<div class="pagination pagination-large">
    -  <ul>
    -    ...
    -  </ul>
    -</div>
    -<div class="pagination">
    -  <ul>
    -    ...
    -  </ul>
    -</div>
    -<div class="pagination pagination-small">
    -  <ul>
    -    ...
    -  </ul>
    -</div>
    -<div class="pagination pagination-mini">
    -  <ul>
    -    ...
    -  </ul>
    -</div>
    -
    - -

    {{_i}}Alignment{{/i}}

    -

    {{_i}}Add one of two optional classes to change the alignment of pagination links: .pagination-centered and .pagination-right.{{/i}}

    -
    - -
    -
    -<div class="pagination pagination-centered">
    -  ...
    -</div>
    -
    -
    - -
    -
    -<div class="pagination pagination-right">
    -  ...
    -</div>
    -
    - - -
    - - -

    {{_i}}Pager{{/i}}

    -

    {{_i}}Quick previous and next links for simple pagination implementations with light markup and styles. It's great for simple sites like blogs or magazines.{{/i}}

    - -

    {{_i}}Default example{{/i}}

    -

    {{_i}}By default, the pager centers links.{{/i}}

    - -
    -<ul class="pager">
    -  <li><a href="#">{{_i}}Previous{{/i}}</a></li>
    -  <li><a href="#">{{_i}}Next{{/i}}</a></li>
    -</ul>
    -
    - -

    {{_i}}Aligned links{{/i}}

    -

    {{_i}}Alternatively, you can align each link to the sides:{{/i}}

    - -
    -<ul class="pager">
    -  <li class="previous">
    -    <a href="#">{{_i}}&larr; Older{{/i}}</a>
    -  </li>
    -  <li class="next">
    -    <a href="#">{{_i}}Newer &rarr;{{/i}}</a>
    -  </li>
    -</ul>
    -
    - -

    {{_i}}Optional disabled state{{/i}}

    -

    {{_i}}Pager links also use the general .disabled utility class from the pagination.{{/i}}

    - -
    -<ul class="pager">
    -  <li class="previous disabled">
    -    <a href="#">{{_i}}&larr; Older{{/i}}</a>
    -  </li>
    -  ...
    -</ul>
    -
    - -
    - - - - -
    - -

    {{_i}}Labels{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Labels{{/i}}{{_i}}Markup{{/i}}
    - {{_i}}Default{{/i}} - - <span class="label">{{_i}}Default{{/i}}</span> -
    - {{_i}}Success{{/i}} - - <span class="label label-success">{{_i}}Success{{/i}}</span> -
    - {{_i}}Warning{{/i}} - - <span class="label label-warning">{{_i}}Warning{{/i}}</span> -
    - {{_i}}Important{{/i}} - - <span class="label label-important">{{_i}}Important{{/i}}</span> -
    - {{_i}}Info{{/i}} - - <span class="label label-info">{{_i}}Info{{/i}}</span> -
    - {{_i}}Inverse{{/i}} - - <span class="label label-inverse">{{_i}}Inverse{{/i}}</span> -
    - -

    {{_i}}Badges{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Name{{/i}}{{_i}}Example{{/i}}{{_i}}Markup{{/i}}
    - {{_i}}Default{{/i}} - - 1 - - <span class="badge">1</span> -
    - {{_i}}Success{{/i}} - - 2 - - <span class="badge badge-success">2</span> -
    - {{_i}}Warning{{/i}} - - 4 - - <span class="badge badge-warning">4</span> -
    - {{_i}}Important{{/i}} - - 6 - - <span class="badge badge-important">6</span> -
    - {{_i}}Info{{/i}} - - 8 - - <span class="badge badge-info">8</span> -
    - {{_i}}Inverse{{/i}} - - 10 - - <span class="badge badge-inverse">10</span> -
    - -

    {{_i}}Easily collapsible{{/i}}

    -

    {{_i}}For easy implementation, labels and badges will simply collapse (via CSS's :empty selector) when no content exists within.{{/i}}

    - -
    - - - - -
    - - -

    {{_i}}Hero unit{{/i}}

    -

    {{_i}}A lightweight, flexible component to showcase key content on your site. It works well on marketing and content-heavy sites.{{/i}}

    -
    -
    -

    {{_i}}Hello, world!{{/i}}

    -

    {{_i}}This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.{{/i}}

    -

    {{_i}}Learn more{{/i}}

    -
    -
    -
    -<div class="hero-unit">
    -  <h1>{{_i}}Heading{{/i}}</h1>
    -  <p>{{_i}}Tagline{{/i}}</p>
    -  <p>
    -    <a class="btn btn-primary btn-large">
    -      {{_i}}Learn more{{/i}}
    -    </a>
    -  </p>
    -</div>
    -
    - -

    {{_i}}Page header{{/i}}

    -

    {{_i}}A simple shell for an h1 to appropriately space out and segment sections of content on a page. It can utilize the h1's default small, element as well most other components (with additional styles).{{/i}}

    -
    - -
    -
    -<div class="page-header">
    -  <h1>{{_i}}Example page header{{/i}} <small>{{_i}}Subtext for header{{/i}}</small></h1>
    -</div>
    -
    - -
    - - - - -
    - - -

    {{_i}}Default thumbnails{{/i}}

    -

    {{_i}}By default, Bootstrap's thumbnails are designed to showcase linked images with minimal required markup.{{/i}}

    -
    - -
    - -

    {{_i}}Highly customizable{{/i}}

    -

    {{_i}}With a bit of extra markup, it's possible to add any kind of HTML content like headings, paragraphs, or buttons into thumbnails.{{/i}}

    -
    -
      -
    • -
      - -
      -

      {{_i}}Thumbnail label{{/i}}

      -

      Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.

      -

      {{_i}}Action{{/i}} {{_i}}Action{{/i}}

      -
      -
      -
    • -
    • -
      - -
      -

      {{_i}}Thumbnail label{{/i}}

      -

      Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.

      -

      {{_i}}Action{{/i}} {{_i}}Action{{/i}}

      -
      -
      -
    • -
    • -
      - -
      -

      {{_i}}Thumbnail label{{/i}}

      -

      Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.

      -

      {{_i}}Action{{/i}} {{_i}}Action{{/i}}

      -
      -
      -
    • -
    -
    - -

    {{_i}}Why use thumbnails{{/i}}

    -

    {{_i}}Thumbnails (previously .media-grid up until v1.4) are great for grids of photos or videos, image search results, retail products, portfolios, and much more. They can be links or static content.{{/i}}

    - -

    {{_i}}Simple, flexible markup{{/i}}

    -

    {{_i}}Thumbnail markup is simple—a ul with any number of li elements is all that is required. It's also super flexible, allowing for any type of content with just a bit more markup to wrap your contents.{{/i}}

    - -

    {{_i}}Uses grid column sizes{{/i}}

    -

    {{_i}}Lastly, the thumbnails component uses existing grid system classes—like .span2 or .span3—for control of thumbnail dimensions.{{/i}}

    - -

    {{_i}}Markup{{/i}}

    -

    {{_i}}As mentioned previously, the required markup for thumbnails is light and straightforward. Here's a look at the default setup for linked images:{{/i}}

    -
    -<ul class="thumbnails">
    -  <li class="span4">
    -    <a href="#" class="thumbnail">
    -      <img data-src="holder.js/300x200" alt="">
    -    </a>
    -  </li>
    -  ...
    -</ul>
    -
    -

    {{_i}}For custom HTML content in thumbnails, the markup changes slightly. To allow block level content anywhere, we swap the <a> for a <div> like so:{{/i}}

    -
    -<ul class="thumbnails">
    -  <li class="span4">
    -    <div class="thumbnail">
    -      <img data-src="holder.js/300x200" alt="">
    -      <h3>{{_i}}Thumbnail label{{/i}}</h3>
    -      <p>{{_i}}Thumbnail caption...{{/i}}</p>
    -    </div>
    -  </li>
    -  ...
    -</ul>
    -
    - -

    {{_i}}More examples{{/i}}

    -

    {{_i}}Explore all your options with the various grid classes available to you. You can also mix and match different sizes.{{/i}}

    - - -
    - - - - - -
    - - -

    {{_i}}Default alert{{/i}}

    -

    {{_i}}Wrap any text and an optional dismiss button in .alert for a basic warning alert message.{{/i}}

    -
    -
    - - {{_i}}Warning!{{/i}} {{_i}}Best check yo self, you're not looking too good.{{/i}} -
    -
    -
    -<div class="alert">
    -  <button type="button" class="close" data-dismiss="alert">&times;</button>
    -  <strong>{{_i}}Warning!{{/i}}</strong> {{_i}}Best check yo self, you're not looking too good.{{/i}}
    -</div>
    -
    - -

    {{_i}}Dismiss buttons{{/i}}

    -

    {{_i}}Mobile Safari and Mobile Opera browsers, in addition to the data-dismiss="alert" attribute, require an href="#" for the dismissal of alerts when using an <a> tag.{{/i}}

    -
    <a href="#" class="close" data-dismiss="alert">&times;</a>
    -

    {{_i}}Alternatively, you may use a <button> element with the data attribute, which we have opted to do for our docs. When using <button>, you must include type="button" or your forms may not submit.{{/i}}

    -
    <button type="button" class="close" data-dismiss="alert">&times;</button>
    - -

    {{_i}}Dismiss alerts via JavaScript{{/i}}

    -

    {{_i}}Use the alerts jQuery plugin for quick and easy dismissal of alerts.{{/i}}

    - - -
    - - -

    {{_i}}Options{{/i}}

    -

    {{_i}}For longer messages, increase the padding on the top and bottom of the alert wrapper by adding .alert-block.{{/i}}

    -
    -
    - -

    {{_i}}Warning!{{/i}}

    -

    {{_i}}Best check yo self, you're not looking too good.{{/i}} Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

    -
    -
    -
    -<div class="alert alert-block">
    -  <button type="button" class="close" data-dismiss="alert">&times;</button>
    -  <h4>{{_i}}Warning!{{/i}}</h4>
    -  {{_i}}Best check yo self, you're not...{{/i}}
    -</div>
    -
    - - -
    - - -

    {{_i}}Contextual alternatives{{/i}}

    -

    {{_i}}Add optional classes to change an alert's connotation.{{/i}}

    - -

    {{_i}}Error or danger{{/i}}

    -
    -
    - - {{_i}}Oh snap!{{/i}} {{_i}}Change a few things up and try submitting again.{{/i}} -
    -
    -
    -<div class="alert alert-error">
    -  ...
    -</div>
    -
    - -

    {{_i}}Success{{/i}}

    -
    -
    - - {{_i}}Well done!{{/i}} {{_i}}You successfully read this important alert message.{{/i}} -
    -
    -
    -<div class="alert alert-success">
    -  ...
    -</div>
    -
    - -

    {{_i}}Information{{/i}}

    -
    -
    - - {{_i}}Heads up!{{/i}} {{_i}}This alert needs your attention, but it's not super important.{{/i}} -
    -
    -
    -<div class="alert alert-info">
    -  ...
    -</div>
    -
    - -
    - - - - - -
    - - -

    {{_i}}Examples and markup{{/i}}

    - -

    {{_i}}Basic{{/i}}

    -

    {{_i}}Default progress bar with a vertical gradient.{{/i}}

    -
    -
    -
    -
    -
    -
    -<div class="progress">
    -  <div class="bar" style="width: 60%;"></div>
    -</div>
    -
    - -

    {{_i}}Striped{{/i}}

    -

    {{_i}}Uses a gradient to create a striped effect. Not available in IE7-8.{{/i}}

    -
    -
    -
    -
    -
    -
    -<div class="progress progress-striped">
    -  <div class="bar" style="width: 20%;"></div>
    -</div>
    -
    - -

    {{_i}}Animated{{/i}}

    -

    {{_i}}Add .active to .progress-striped to animate the stripes right to left. Not available in all versions of IE.{{/i}}

    -
    -
    -
    -
    -
    -
    -<div class="progress progress-striped active">
    -  <div class="bar" style="width: 40%;"></div>
    -</div>
    -
    - -

    Stacked

    -

    Place multiple bars into the same .progress to stack them.

    -
    -
    -
    -
    -
    -
    -
    -
    -<div class="progress">
    -  <div class="bar bar-success" style="width: 35%;"></div>
    -  <div class="bar bar-warning" style="width: 20%;"></div>
    -  <div class="bar bar-danger" style="width: 10%;"></div>
    -</div>
    -
    - - -
    - - -

    {{_i}}Options{{/i}}

    - -

    {{_i}}Additional colors{{/i}}

    -

    {{_i}}Progress bars use some of the same button and alert classes for consistent styles.{{/i}}

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -<div class="progress progress-info">
    -  <div class="bar" style="width: 20%"></div>
    -</div>
    -<div class="progress progress-success">
    -  <div class="bar" style="width: 40%"></div>
    -</div>
    -<div class="progress progress-warning">
    -  <div class="bar" style="width: 60%"></div>
    -</div>
    -<div class="progress progress-danger">
    -  <div class="bar" style="width: 80%"></div>
    -</div>
    -
    - -

    {{_i}}Striped bars{{/i}}

    -

    {{_i}}Similar to the solid colors, we have varied striped progress bars.{{/i}}

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -<div class="progress progress-info progress-striped">
    -  <div class="bar" style="width: 20%"></div>
    -</div>
    -<div class="progress progress-success progress-striped">
    -  <div class="bar" style="width: 40%"></div>
    -</div>
    -<div class="progress progress-warning progress-striped">
    -  <div class="bar" style="width: 60%"></div>
    -</div>
    -<div class="progress progress-danger progress-striped">
    -  <div class="bar" style="width: 80%"></div>
    -</div>
    -
    - - -
    - - -

    {{_i}}Browser support{{/i}}

    -

    {{_i}}Progress bars use CSS3 gradients, transitions, and animations to achieve all their effects. These features are not supported in IE7-9 or older versions of Firefox.{{/i}}

    -

    {{_i}}Versions earlier than Internet Explorer 10 and Opera 12 do not support animations.{{/i}}

    - -
    - - - - - -
    - -

    {{_i}}Abstract object styles for building various types of components (like blog comments, Tweets, etc) that feature a left- or right-aligned image alongside textual content.{{/i}}

    - -

    {{_i}}Default example{{/i}}

    -

    {{_i}}The default media allow to float a media object (images, video, audio) to the left or right of a content block.{{/i}}

    -
    -
    - - - -
    -

    {{_i}}Media heading{{/i}}

    - Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. -
    -
    -
    - - - -
    -

    {{_i}}Media heading{{/i}}

    - Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. -
    - - - -
    -

    {{_i}}Media heading{{/i}}

    - Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus. -
    -
    -
    -
    -
    {{! /.bs-docs-example }} -
    -<div class="media">
    -  <a class="pull-left" href="#">
    -    <img class="media-object" data-src="holder.js/64x64">
    -  </a>
    -  <div class="media-body">
    -    <h4 class="media-heading">{{_i}}Media heading{{/i}}</h4>
    -    ...
    -
    -    <!-- Nested media object -->
    -    <div class="media">
    -      ...
    -    </div>
    -  </div>
    -</div>
    -
    - - -
    - - -

    {{_i}}Media list{{/i}}

    -

    {{_i}}With a bit of extra markup, you can use media inside list (useful for comment threads or articles lists).{{/i}}

    -
    -
      -
    • - - - -
      -

      {{_i}}Media heading{{/i}}

      -

      Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis.

      - -
      - - - -
      -

      {{_i}}Nested media heading{{/i}}

      - Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. - -
      - - - -
      -

      {{_i}}Nested media heading{{/i}}

      - Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. -
      -
      -
      -
      - -
      - - - -
      -

      {{_i}}Nested media heading{{/i}}

      - Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. -
      -
      -
      -
    • -
    • - - - -
      -

      {{_i}}Media heading{{/i}}

      - Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin commodo. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. -
      -
    • -
    -
    -
    -<ul class="media-list">
    -  <li class="media">
    -    <a class="pull-left" href="#">
    -      <img class="media-object" data-src="holder.js/64x64">
    -    </a>
    -    <div class="media-body">
    -      <h4 class="media-heading">{{_i}}Media heading{{/i}}</h4>
    -      ...
    -
    -      <!-- Nested media object -->
    -      <div class="media">
    -        ...
    -     </div>
    -    </div>
    -  </li>
    -</ul>
    -
    - -
    - - - - - - -
    - - -

    {{_i}}Wells{{/i}}

    -

    {{_i}}Use the well as a simple effect on an element to give it an inset effect.{{/i}}

    -
    -
    - {{_i}}Look, I'm in a well!{{/i}} -
    -
    -
    -<div class="well">
    -  ...
    -</div>
    -
    -

    {{_i}}Optional classes{{/i}}

    -

    {{_i}}Control padding and rounded corners with two optional modifier classes.{{/i}}

    -
    -
    - {{_i}}Look, I'm in a well!{{/i}} -
    -
    -
    -<div class="well well-large">
    -  ...
    -</div>
    -
    -
    -
    - {{_i}}Look, I'm in a well!{{/i}} -
    -
    -
    -<div class="well well-small">
    -  ...
    -</div>
    -
    - -

    {{_i}}Close icon{{/i}}

    -

    {{_i}}Use the generic close icon for dismissing content like modals and alerts.{{/i}}

    -
    -

    -
    -
    <button class="close">&times;</button>
    -

    {{_i}}iOS devices require an href="#" for click events if you would rather use an anchor.{{/i}}

    -
    <a class="close" href="#">&times;</a>
    - -

    {{_i}}Helper classes{{/i}}

    -

    {{_i}}Simple, focused classes for small display or behavior tweaks.{{/i}}

    - -

    {{_i}}.pull-left{{/i}}

    -

    {{_i}}Float an element left{{/i}}

    -
    -class="pull-left"
    -
    -
    -.pull-left {
    -  float: left;
    -}
    -
    - -

    {{_i}}.pull-right{{/i}}

    -

    {{_i}}Float an element right{{/i}}

    -
    -class="pull-right"
    -
    -
    -.pull-right {
    -  float: right;
    -}
    -
    - -

    {{_i}}.muted{{/i}}

    -

    {{_i}}Change an element's color to #999{{/i}}

    -
    -class="muted"
    -
    -
    -.muted {
    -  color: #999;
    -}
    -
    - -

    {{_i}}.clearfix{{/i}}

    -

    {{_i}}Clear the float on any element{{/i}}

    -
    -class="clearfix"
    -
    -
    -.clearfix {
    -  *zoom: 1;
    -  &:before,
    -  &:after {
    -    display: table;
    -    content: "";
    -  }
    -  &:after {
    -    clear: both;
    -  }
    -}
    -
    - -
    - - - -
    {{! /span9 }} -
    {{! row}} - -
    {{! /.container }} diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/customize.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/pages/customize.mustache deleted file mode 100644 index 8d8a2f92a..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/customize.mustache +++ /dev/null @@ -1,393 +0,0 @@ - -
    -
    -

    {{_i}}Customize and download{{/i}}

    -

    {{_i}}Download Bootstrap or customize variables, components, JavaScript plugins, and more.{{/i}}

    -
    -
    - - -
    - - -
    - -
    - - - -
    -
    - -
    -
    -

    {{_i}}Scaffolding{{/i}}

    - - - - -

    {{_i}}Base CSS{{/i}}

    - - - - - - - -
    -
    -

    {{_i}}Components{{/i}}

    - - - - - - - - - - - -

    {{_i}}JS Components{{/i}}

    - - - - - - -
    -
    -

    {{_i}}Miscellaneous{{/i}}

    - - - - -

    {{_i}}Responsive{{/i}}

    - - - - - -
    -
    -
    - -
    - -
    -
    - - - - - - - -
    -
    - - - - - - -
    -
    -

    {{_i}}Heads up!{{/i}}

    -

    {{_i}}All checked plugins will be compiled into a single file, bootstrap.js. All plugins require the latest version of jQuery to be included.{{/i}}

    -
    -
    -
    - - -
    - -
    -
    -

    {{_i}}Scaffolding{{/i}}

    - - - - - -

    {{_i}}Links{{/i}}

    - - - - -

    {{_i}}Colors{{/i}}

    - - - - - - - - - - - - - - - -

    {{_i}}Sprites{{/i}}

    - - - - - -

    {{_i}}Grid system{{/i}}

    - - - - - - - - - - - - - - - -
    -
    - -

    {{_i}}Typography{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    {{_i}}Tables{{/i}}

    - - - - - - - - - -

    {{_i}}Forms{{/i}}

    - - - - - - - - - - - - - - - - - -
    -
    - -

    {{_i}}Form states & alerts{{/i}}

    - - - - - - - - - - - - - - - - - -

    {{_i}}Navbar{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    {{_i}}Dropdowns{{/i}}

    - - - - - - - - - - -
    -
    -
    - -
    - -
    - {{_i}}Customize and Download{{/i}} -

    {{_i}}What's included?{{/i}}

    -

    {{_i}}Downloads include compiled CSS, compiled and minified CSS, and compiled jQuery plugins, all nicely packed up into a zipball for your convenience.{{/i}}

    -
    -
    -
    - - - -
    {{! /span9 }} -
    {{! row}} - -
    {{! /.container }} diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/extend.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/pages/extend.mustache deleted file mode 100644 index b5c8d5747..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/extend.mustache +++ /dev/null @@ -1,161 +0,0 @@ - -
    -
    -

    {{_i}}Extending Bootstrap{{/i}}

    -

    {{_i}}Extend Bootstrap to take advantage of included styles and components, as well as LESS variables and mixins.{{/i}}

    -
    -
    - -
    - - -
    - -
    - - - - -
    - - - LESS CSS -

    {{_i}}Bootstrap is made with LESS at its core, a dynamic stylesheet language created by our good friend, Alexis Sellier. It makes developing systems-based CSS faster, easier, and more fun.{{/i}}

    - -

    {{_i}}Why LESS?{{/i}}

    -

    {{_i}}One of Bootstrap's creators wrote a quick blog post about this, summarized here:{{/i}}

    -
      -
    • {{_i}}Bootstrap compiles faster ~6x faster with Less compared to Sass{{/i}}
    • -
    • {{_i}}Less is written in JavaScript, making it easier to us to dive in and patch compared to Ruby with Sass.{{/i}}
    • -
    • {{_i}}Less is more; we want to feel like we're writing CSS and making Bootstrap approachable to all.{{/i}}
    • -
    - -

    {{_i}}What's included?{{/i}}

    -

    {{_i}}As an extension of CSS, LESS includes variables, mixins for reusable snippets of code, operations for simple math, nesting, and even color functions.{{/i}}

    - -

    {{_i}}Learn more{{/i}}

    -

    {{_i}}Visit the official website at http://lesscss.org to learn more.{{/i}}

    -
    - - - - -
    - - -

    {{_i}}Since our CSS is written with Less and utilizes variables and mixins, it needs to be compiled for final production implementation. Here's how.{{/i}}

    - -
    - {{_i}}Note: If you're submitting a pull request to GitHub with modified CSS, you must recompile the CSS via any of these methods.{{/i}} -
    - -

    {{_i}}Tools for compiling{{/i}}

    - -

    {{_i}}Command line{{/i}}

    -

    {{_i}}Follow the instructions in the project readme on GitHub for compiling via command line.{{/i}}

    - -

    {{_i}}JavaScript{{/i}}

    -

    {{_i}}Download the latest Less.js and include the path to it (and Bootstrap) in the <head>.{{/i}}

    -
    -<link rel="stylesheet/less" href="/path/to/bootstrap.less">
    -<script src="/path/to/less.js"></script>
    -
    -

    {{_i}}To recompile the .less files, just save them and reload your page. Less.js compiles them and stores them in local storage.{{/i}}

    - -

    {{_i}}Unofficial Mac app{{/i}}

    -

    {{_i}}The unofficial Mac app watches directories of .less files and compiles the code to local files after every save of a watched .less file. If you like, you can toggle preferences in the app for automatic minifying and which directory the compiled files end up in.{{/i}}

    - -

    {{_i}}More apps{{/i}}

    -

    Crunch

    -

    {{_i}}Crunch is a great looking LESS editor and compiler built on Adobe Air.{{/i}}

    -

    CodeKit

    -

    {{_i}}Created by the same guy as the unofficial Mac app, CodeKit is a Mac app that compiles LESS, SASS, Stylus, and CoffeeScript.{{/i}}

    -

    Simpless

    -

    {{_i}}Mac, Linux, and Windows app for drag and drop compiling of LESS files. Plus, the source code is on GitHub.{{/i}}

    - -
    - - - - -
    - -

    {{_i}}Quickly start any web project by dropping in the compiled or minified CSS and JS. Layer on custom styles separately for easy upgrades and maintenance moving forward.{{/i}}

    - -

    {{_i}}Setup file structure{{/i}}

    -

    {{_i}}Download the latest compiled Bootstrap and place into your project. For example, you might have something like this:{{/i}}

    -
    -   app/
    -       layouts/
    -       templates/
    -   public/
    -       css/
    -           bootstrap.min.css
    -       js/
    -           bootstrap.min.js
    -       img/
    -           glyphicons-halflings.png
    -           glyphicons-halflings-white.png
    -
    - -

    {{_i}}Utilize starter template{{/i}}

    -

    {{_i}}Copy the following base HTML to get started.{{/i}}

    -
    -<html>
    -  <head>
    -    <title>Bootstrap 101 Template</title>
    -    <!-- Bootstrap -->
    -    <link href="public/css/bootstrap.min.css" rel="stylesheet">
    -  </head>
    -  <body>
    -    <h1>Hello, world!</h1>
    -    <!-- Bootstrap -->
    -    <script src="public/js/bootstrap.min.js"></script>
    -  </body>
    -</html>
    -
    - -

    {{_i}}Layer on custom code{{/i}}

    -

    {{_i}}Work in your custom CSS, JS, and more as necessary to make Bootstrap your own with your own separate CSS and JS files.{{/i}}

    -
    -<html>
    -  <head>
    -    <title>Bootstrap 101 Template</title>
    -    <!-- Bootstrap -->
    -    <link href="public/css/bootstrap.min.css" rel="stylesheet">
    -    <!-- Project -->
    -    <link href="public/css/application.css" rel="stylesheet">
    -  </head>
    -  <body>
    -    <h1>Hello, world!</h1>
    -    <!-- Bootstrap -->
    -    <script src="public/js/bootstrap.min.js"></script>
    -    <!-- Project -->
    -    <script src="public/js/application.js"></script>
    -  </body>
    -</html>
    -
    - -
    - -
    {{! /span9 }} -
    {{! row}} - -
    {{! /.container }} diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/getting-started.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/pages/getting-started.mustache deleted file mode 100644 index ae1534ce3..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/getting-started.mustache +++ /dev/null @@ -1,256 +0,0 @@ - -
    -
    -

    {{_i}}Getting started{{/i}}

    -

    {{_i}}Overview of the project, its contents, and how to get started with a simple template.{{/i}}

    -
    -
    - - -
    - - -
    - -
    - - - - -
    - -

    {{_i}}Before downloading, be sure to have a code editor (we recommend Sublime Text 2) and some working knowledge of HTML and CSS. We won't walk through the source files here, but they are available for download. We'll focus on getting started with the compiled Bootstrap files.{{/i}}

    - -
    -
    -

    {{_i}}Download compiled{{/i}}

    -

    {{_i}}Fastest way to get started: get the compiled and minified versions of our CSS, JS, and images. No docs or original source files.{{/i}}

    -

    {{_i}}Download Bootstrap{{/i}}

    -
    -
    -

    Download source

    -

    Get the original files for all CSS and JavaScript, along with a local copy of the docs by downloading the latest version directly from GitHub.

    -

    {{_i}}Download Bootstrap source{{/i}}

    -
    -
    -
    - - - - -
    - -

    {{_i}}Within the download you'll find the following file structure and contents, logically grouping common assets and providing both compiled and minified variations.{{/i}}

    -

    {{_i}}Once downloaded, unzip the compressed folder to see the structure of (the compiled) Bootstrap. You'll see something like this:{{/i}}

    -
    -  bootstrap/
    -  ├── css/
    -  │   ├── bootstrap.css
    -  │   ├── bootstrap.min.css
    -  ├── js/
    -  │   ├── bootstrap.js
    -  │   ├── bootstrap.min.js
    -  └── img/
    -      ├── glyphicons-halflings.png
    -      └── glyphicons-halflings-white.png
    -
    -

    {{_i}}This is the most basic form of Bootstrap: compiled files for quick drop-in usage in nearly any web project. We provide compiled CSS and JS (bootstrap.*), as well as compiled and minified CSS and JS (bootstrap.min.*). The image files are compressed using ImageOptim, a Mac app for compressing PNGs.{{/i}}

    -

    {{_i}}Please note that all JavaScript plugins require jQuery to be included.{{/i}}

    -
    - - - - -
    - -

    {{_i}}Bootstrap comes equipped with HTML, CSS, and JS for all sorts of things, but they can be summarized with a handful of categories visible at the top of the Bootstrap documentation.{{/i}}

    - -

    {{_i}}Docs sections{{/i}}

    -

    {{_i}}Scaffolding{{/i}}

    -

    {{_i}}Global styles for the body to reset type and background, link styles, grid system, and two simple layouts.{{/i}}

    -

    {{_i}}Base CSS{{/i}}

    -

    {{_i}}Styles for common HTML elements like typography, code, tables, forms, and buttons. Also includes Glyphicons, a great little icon set.{{/i}}

    -

    {{_i}}Components{{/i}}

    -

    {{_i}}Basic styles for common interface components like tabs and pills, navbar, alerts, page headers, and more.{{/i}}

    -

    {{_i}}JavaScript plugins{{/i}}

    -

    {{_i}}Similar to Components, these JavaScript plugins are interactive components for things like tooltips, popovers, modals, and more.{{/i}}

    - -

    {{_i}}List of components{{/i}}

    -

    {{_i}}Together, the Components and JavaScript plugins sections provide the following interface elements:{{/i}}

    -
      -
    • {{_i}}Button groups{{/i}}
    • -
    • {{_i}}Button dropdowns{{/i}}
    • -
    • {{_i}}Navigational tabs, pills, and lists{{/i}}
    • -
    • {{_i}}Navbar{{/i}}
    • -
    • {{_i}}Labels{{/i}}
    • -
    • {{_i}}Badges{{/i}}
    • -
    • {{_i}}Page headers and hero unit{{/i}}
    • -
    • {{_i}}Thumbnails{{/i}}
    • -
    • {{_i}}Alerts{{/i}}
    • -
    • {{_i}}Progress bars{{/i}}
    • -
    • {{_i}}Modals{{/i}}
    • -
    • {{_i}}Dropdowns{{/i}}
    • -
    • {{_i}}Tooltips{{/i}}
    • -
    • {{_i}}Popovers{{/i}}
    • -
    • {{_i}}Accordion{{/i}}
    • -
    • {{_i}}Carousel{{/i}}
    • -
    • {{_i}}Typeahead{{/i}}
    • -
    -

    {{_i}}In future guides, we may walk through these components individually in more detail. Until then, look for each of these in the documentation for information on how to utilize and customize them.{{/i}}

    -
    - - - - -
    - -

    {{_i}}With a brief intro into the contents out of the way, we can focus on putting Bootstrap to use. To do that, we'll utilize a basic HTML template that includes everything we mentioned in the File structure.{{/i}}

    -

    {{_i}}Now, here's a look at a typical HTML file:{{/i}}

    -
    -<!DOCTYPE html>
    -<html>
    -  <head>
    -    <title>Bootstrap 101 Template</title>
    -    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    -  </head>
    -  <body>
    -    <h1>Hello, world!</h1>
    -    <script src="http://code.jquery.com/jquery.js"></script>
    -  </body>
    -</html>
    -
    -

    {{_i}}To make this a Bootstrapped template, just include the appropriate CSS and JS files:{{/i}}

    -
    -<!DOCTYPE html>
    -<html>
    -  <head>
    -    <title>Bootstrap 101 Template</title>
    -    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    -    <!-- Bootstrap -->
    -    <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
    -  </head>
    -  <body>
    -    <h1>Hello, world!</h1>
    -    <script src="http://code.jquery.com/jquery.js"></script>
    -    <script src="js/bootstrap.min.js"></script>
    -  </body>
    -</html>
    -
    -

    {{_i}}And you're set! With those two files added, you can begin to develop any site or application with Bootstrap.{{/i}}

    -
    - - - - -
    - -

    {{_i}}Move beyond the base template with a few example layouts. We encourage folks to iterate on these examples and not simply use them as an end result.{{/i}}

    -
      -
    • - - - -

      {{_i}}Starter template{{/i}}

      -

      {{_i}}A barebones HTML document with all the Bootstrap CSS and JavaScript included.{{/i}}

      -
    • -
    • - - - -

      {{_i}}Basic marketing site{{/i}}

      -

      {{_i}}Featuring a hero unit for a primary message and three supporting elements.{{/i}}

      -
    • -
    • - - - -

      {{_i}}Fluid layout{{/i}}

      -

      {{_i}}Uses our new responsive, fluid grid system to create a seamless liquid layout.{{/i}}

      -
    • - -
    • - - - -

      {{_i}}Narrow marketing{{/i}}

      -

      {{_i}}Slim, lightweight marketing template for small projects or teams.{{/i}}

      -
    • -
    • - - - -

      {{_i}}Justified nav{{/i}}

      -

      {{_i}}Marketing page with equal-width navigation links in a modified navbar.{{/i}}

      -
    • -
    • - - - -

      {{_i}}Sign in{{/i}}

      -

      {{_i}}Barebones sign in form with custom, larger form controls and a flexible layout.{{/i}}

      -
    • - -
    • - - - -

      {{_i}}Sticky footer{{/i}}

      -

      {{_i}}Pin a fixed-height footer to the bottom of the user's viewport.{{/i}}

      -
    • -
    • - - - -

      {{_i}}Carousel jumbotron{{/i}}

      -

      {{_i}}A more interactive riff on the basic marketing site featuring a prominent carousel.{{/i}}

      -
    • -
    -
    - - - - - -
    - -

    {{_i}}Head to the docs for information, examples, and code snippets, or take the next leap and customize Bootstrap for any upcoming project.{{/i}}

    - {{_i}}Visit the Bootstrap docs{{/i}} - {{_i}}Customize Bootstrap{{/i}} -
    - - - - -
    {{! /span9 }} -
    {{! row}} - -
    {{! /.container }} diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/index.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/pages/index.mustache deleted file mode 100644 index b38ddec25..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/index.mustache +++ /dev/null @@ -1,100 +0,0 @@ -
    -
    -

    {{_i}}Bootstrap{{/i}}

    -

    {{_i}}Sleek, intuitive, and powerful front-end framework for faster and easier web development.{{/i}}

    -

    - {{_i}}Download Bootstrap{{/i}} -

    - -
    -
    - -
    -
    - -
    -
    - -
    - -
    - -

    {{_i}}Introducing Bootstrap.{{/i}}

    - - -
    -
    - -

    {{_i}}By nerds, for nerds.{{/i}}

    -

    {{_i}}Built at Twitter by @mdo and @fat, Bootstrap utilizes LESS CSS, is compiled via Node, and is managed through GitHub to help nerds do awesome stuff on the web.{{/i}}

    -
    -
    - -

    {{_i}}Made for everyone.{{/i}}

    -

    {{_i}}Bootstrap was made to not only look and behave great in the latest desktop browsers (as well as IE7!), but in tablet and smartphone browsers via responsive CSS as well.{{/i}}

    -
    -
    - -

    {{_i}}Packed with features.{{/i}}

    -

    {{_i}}A 12-column responsive grid, dozens of components, JavaScript plugins, typography, form controls, and even a web-based Customizer to make Bootstrap your own.{{/i}}

    -
    -
    - -
    - -

    {{_i}}Built with Bootstrap.{{/i}}

    - -
    - -
    - -
    {{! /.marketing }} - -
    {{! /.container }} diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/javascript.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/pages/javascript.mustache deleted file mode 100644 index 744988f4b..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/javascript.mustache +++ /dev/null @@ -1,1660 +0,0 @@ - -
    -
    -

    {{_i}}JavaScript{{/i}}

    -

    {{_i}}Bring Bootstrap's components to life—now with 13 custom jQuery plugins.{{/i}} -

    -
    - -
    - - -
    - -
    - - - -
    - - -

    {{_i}}Individual or compiled{{/i}}

    -

    {{_i}}Plugins can be included individually (though some have required dependencies), or all at once. Both bootstrap.js and bootstrap.min.js contain all plugins in a single file.{{/i}}

    - -

    {{_i}}Data attributes{{/i}}

    -

    {{_i}}You can use all Bootstrap plugins purely through the markup API without writing a single line of JavaScript. This is Bootstrap's first class API and should be your first consideration when using a plugin.{{/i}}

    - -

    {{_i}}That said, in some situations it may be desirable to turn this functionality off. Therefore, we also provide the ability to disable the data attribute API by unbinding all events on the body namespaced with `'data-api'`. This looks like this:{{/i}} -

    $('body').off('.data-api')
    - -

    {{_i}}Alternatively, to target a specific plugin, just include the plugin's name as a namespace along with the data-api namespace like this:{{/i}}

    -
    $('body').off('.alert.data-api')
    - -

    {{_i}}Programmatic API{{/i}}

    -

    {{_i}}We also believe you should be able to use all Bootstrap plugins purely through the JavaScript API. All public APIs are single, chainable methods, and return the collection acted upon.{{/i}}

    -
    $(".btn.danger").button("toggle").addClass("fat")
    -

    {{_i}}All methods should accept an optional options object, a string which targets a particular method, or nothing (which initiates a plugin with default behavior):{{/i}}

    -
    -$("#myModal").modal()                       // initialized with defaults
    -$("#myModal").modal({ keyboard: false })   // initialized with no keyboard
    -$("#myModal").modal('show')                // initializes and invokes show immediately

    -
    -

    {{_i}}Each plugin also exposes its raw constructor on a `Constructor` property: $.fn.popover.Constructor. If you'd like to get a particular plugin instance, retrieve it directly from an element: $('[rel=popover]').data('popover').{{/i}}

    - -

    {{_i}}No Conflict{{/i}}

    -

    {{_i}}Sometimes it is necessary to use Bootstrap plugins with other UI frameworks. In these circumstances, namespace collisions can occasionally occur. If this happens, you may call .noConflict on the plugin you wish to revert the value of.{{/i}}

    - -
    -var bootstrapButton = $.fn.button.noConflict() // return $.fn.button to previously assigned value
    -$.fn.bootstrapBtn = bootstrapButton            // give $().bootstrapBtn the bootstrap functionality
    -
    - -

    {{_i}}Events{{/i}}

    -

    {{_i}}Bootstrap provides custom events for most plugin's unique actions. Generally, these come in an infinitive and past participle form - where the infinitive (ex. show) is triggered at the start of an event, and its past participle form (ex. shown) is trigger on the completion of an action.{{/i}}

    -

    {{_i}}All infinitive events provide preventDefault functionality. This provides the ability to stop the execution of an action before it starts.{{/i}}

    -
    -$('#myModal').on('show', function (e) {
    -    if (!data) return e.preventDefault() // stops modal from being shown
    -})
    -
    -
    - - - - -
    - -

    {{_i}}About transitions{{/i}}

    -

    {{_i}}For simple transition effects, include bootstrap-transition.js once alongside the other JS files. If you're using the compiled (or minified) bootstrap.js, there is no need to include this—it's already there.{{/i}}

    -

    {{_i}}Use cases{{/i}}

    -

    {{_i}}A few examples of the transition plugin:{{/i}}

    -
      -
    • {{_i}}Sliding or fading in modals{{/i}}
    • -
    • {{_i}}Fading out tabs{{/i}}
    • -
    • {{_i}}Fading out alerts{{/i}}
    • -
    • {{_i}}Sliding carousel panes{{/i}}
    • -
    - - {{! Ideas: include docs for .fade.in, .slide.in, etc }} -
    - - - - -
    - - - -

    {{_i}}Examples{{/i}}

    -

    {{_i}}Modals are streamlined, but flexible, dialog prompts with the minimum required functionality and smart defaults.{{/i}}

    - -

    {{_i}}Static example{{/i}}

    -

    {{_i}}A rendered modal with header, body, and set of actions in the footer.{{/i}}

    -
    - -
    {{! /example }} -
    -<div class="modal hide fade">
    -  <div class="modal-header">
    -    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    -    <h3>{{_i}}Modal header{{/i}}</h3>
    -  </div>
    -  <div class="modal-body">
    -    <p>{{_i}}One fine body…{{/i}}</p>
    -  </div>
    -  <div class="modal-footer">
    -    <a href="#" class="btn">{{_i}}Close{{/i}}</a>
    -    <a href="#" class="btn btn-primary">{{_i}}Save changes{{/i}}</a>
    -  </div>
    -</div>
    -
    - -

    {{_i}}Live demo{{/i}}

    -

    {{_i}}Toggle a modal via JavaScript by clicking the button below. It will slide down and fade in from the top of the page.{{/i}}

    - - - {{! /example }} -
    -<!-- Button to trigger modal -->
    -<a href="#myModal" role="button" class="btn" data-toggle="modal">{{_i}}Launch demo modal{{/i}}</a>
    -
    -<!-- Modal -->
    -<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    -  <div class="modal-header">
    -    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    -    <h3 id="myModalLabel">Modal header</h3>
    -  </div>
    -  <div class="modal-body">
    -    <p>{{_i}}One fine body…{{/i}}</p>
    -  </div>
    -  <div class="modal-footer">
    -    <button class="btn" data-dismiss="modal" aria-hidden="true">{{_i}}Close{{/i}}</button>
    -    <button class="btn btn-primary">{{_i}}Save changes{{/i}}</button>
    -  </div>
    -</div>
    -
    - - -
    - - -

    {{_i}}Usage{{/i}}

    - -

    {{_i}}Via data attributes{{/i}}

    -

    {{_i}}Activate a modal without writing JavaScript. Set data-toggle="modal" on a controller element, like a button, along with a data-target="#foo" or href="#foo" to target a specific modal to toggle.{{/i}}

    -
    <button type="button" data-toggle="modal" data-target="#myModal">Launch modal</button>
    - -

    {{_i}}Via JavaScript{{/i}}

    -

    {{_i}}Call a modal with id myModal with a single line of JavaScript:{{/i}}

    -
    $('#myModal').modal(options)
    - -

    {{_i}}Options{{/i}}

    -

    {{_i}}Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-backdrop="".{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Name{{/i}}{{_i}}type{{/i}}{{_i}}default{{/i}}{{_i}}description{{/i}}
    {{_i}}backdrop{{/i}}{{_i}}boolean{{/i}}{{_i}}true{{/i}}{{_i}}Includes a modal-backdrop element. Alternatively, specify static for a backdrop which doesn't close the modal on click.{{/i}}
    {{_i}}keyboard{{/i}}{{_i}}boolean{{/i}}{{_i}}true{{/i}}{{_i}}Closes the modal when escape key is pressed{{/i}}
    {{_i}}show{{/i}}{{_i}}boolean{{/i}}{{_i}}true{{/i}}{{_i}}Shows the modal when initialized.{{/i}}
    {{_i}}remote{{/i}}{{_i}}path{{/i}}{{_i}}false{{/i}}

    {{_i}}If a remote url is provided, content will be loaded via jQuery's load method and injected into the .modal-body. If you're using the data api, you may alternatively use the href tag to specify the remote source. An example of this is shown below:{{/i}}

    -
    <a data-toggle="modal" href="remote.html" data-target="#modal">click me</a>
    - - Methods{{/i}} -

    .modal({{_i}}options{{/i}})

    -

    {{_i}}Activates your content as a modal. Accepts an optional options object.{{/i}}

    -
    -$('#myModal').modal({
    -  keyboard: false
    -})
    -
    -

    .modal('toggle')

    -

    {{_i}}Manually toggles a modal.{{/i}}

    -
    $('#myModal').modal('toggle')
    -

    .modal('show')

    -

    {{_i}}Manually opens a modal.{{/i}}

    -
    $('#myModal').modal('show')
    -

    .modal('hide')

    -

    {{_i}}Manually hides a modal.{{/i}}

    -
    $('#myModal').modal('hide')
    -

    {{_i}}Events{{/i}}

    -

    {{_i}}Bootstrap's modal class exposes a few events for hooking into modal functionality.{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Event{{/i}}{{_i}}Description{{/i}}
    {{_i}}show{{/i}}{{_i}}This event fires immediately when the show instance method is called.{{/i}}
    {{_i}}shown{{/i}}{{_i}}This event is fired when the modal has been made visible to the user (will wait for css transitions to complete).{{/i}}
    {{_i}}hide{{/i}}{{_i}}This event is fired immediately when the hide instance method has been called.{{/i}}
    {{_i}}hidden{{/i}}{{_i}}This event is fired when the modal has finished being hidden from the user (will wait for css transitions to complete).{{/i}}
    -
    -$('#myModal').on('hidden', function () {
    -  // {{_i}}do something…{{/i}}
    -})
    -
    -
    - - - - - - - - - -
    - - - -

    {{_i}}Example in navbar{{/i}}

    -

    {{_i}}The ScrollSpy plugin is for automatically updating nav targets based on scroll position. Scroll the area below the navbar and watch the active class change. The dropdown sub items will be highlighted as well.{{/i}}

    -
    - -
    -

    @fat

    -

    Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

    -

    @mdo

    -

    Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard. Freegan beard aliqua cupidatat mcsweeney's vero. Cupidatat four loko nisi, ea helvetica nulla carles. Tattooed cosby sweater food truck, mcsweeney's quis non freegan vinyl. Lo-fi wes anderson +1 sartorial. Carles non aesthetic exercitation quis gentrify. Brooklyn adipisicing craft beer vice keytar deserunt.

    -

    one

    -

    Occaecat commodo aliqua delectus. Fap craft beer deserunt skateboard ea. Lomo bicycle rights adipisicing banh mi, velit ea sunt next level locavore single-origin coffee in magna veniam. High life id vinyl, echo park consequat quis aliquip banh mi pitchfork. Vero VHS est adipisicing. Consectetur nisi DIY minim messenger bag. Cred ex in, sustainable delectus consectetur fanny pack iphone.

    -

    two

    -

    In incididunt echo park, officia deserunt mcsweeney's proident master cleanse thundercats sapiente veniam. Excepteur VHS elit, proident shoreditch +1 biodiesel laborum craft beer. Single-origin coffee wayfarers irure four loko, cupidatat terry richardson master cleanse. Assumenda you probably haven't heard of them art party fanny pack, tattooed nulla cardigan tempor ad. Proident wolf nesciunt sartorial keffiyeh eu banh mi sustainable. Elit wolf voluptate, lo-fi ea portland before they sold out four loko. Locavore enim nostrud mlkshk brooklyn nesciunt.

    -

    three

    -

    Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

    -

    Keytar twee blog, culpa messenger bag marfa whatever delectus food truck. Sapiente synth id assumenda. Locavore sed helvetica cliche irony, thundercats you probably haven't heard of them consequat hoodie gluten-free lo-fi fap aliquip. Labore elit placeat before they sold out, terry richardson proident brunch nesciunt quis cosby sweater pariatur keffiyeh ut helvetica artisan. Cardigan craft beer seitan readymade velit. VHS chambray laboris tempor veniam. Anim mollit minim commodo ullamco thundercats. -

    -
    -
    {{! /example }} - - -
    - - -

    {{_i}}Usage{{/i}}

    - -

    {{_i}}Via data attributes{{/i}}

    -

    {{_i}}To easily add scrollspy behavior to your topbar navigation, just add data-spy="scroll" to the element you want to spy on (most typically this would be the body) and data-target=".navbar" to select which nav to use. You'll want to use scrollspy with a .nav component.{{/i}}

    -
    <body data-spy="scroll" data-target=".navbar">...</body>
    - -

    {{_i}}Via JavaScript{{/i}}

    -

    {{_i}}Call the scrollspy via JavaScript:{{/i}}

    -
    $('#navbar').scrollspy()
    - -
    - {{_i}}Heads up!{{/i}} - {{_i}}Navbar links must have resolvable id targets. For example, a <a href="#home">home</a> must correspond to something in the dom like <div id="home"></div>.{{/i}} -
    - -

    {{_i}}Methods{{/i}}

    -

    .scrollspy('refresh')

    -

    {{_i}}When using scrollspy in conjunction with adding or removing of elements from the DOM, you'll need to call the refresh method like so:{{/i}}

    -
    -$('[data-spy="scroll"]').each(function () {
    -  var $spy = $(this).scrollspy('refresh')
    -});
    -
    - -

    {{_i}}Options{{/i}}

    -

    {{_i}}Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-offset="".{{/i}}

    - - - - - - - - - - - - - - - - - -
    {{_i}}Name{{/i}}{{_i}}type{{/i}}{{_i}}default{{/i}}{{_i}}description{{/i}}
    {{_i}}offset{{/i}}{{_i}}number{{/i}}{{_i}}10{{/i}}{{_i}}Pixels to offset from top when calculating position of scroll.{{/i}}
    - -

    {{_i}}Events{{/i}}

    - - - - - - - - - - - - - -
    {{_i}}Event{{/i}}{{_i}}Description{{/i}}
    {{_i}}activate{{/i}}{{_i}}This event fires whenever a new item becomes activated by the scrollspy.{{/i}}
    -
    - - - - -
    - - - -

    {{_i}}Example tabs{{/i}}

    -

    {{_i}}Add quick, dynamic tab functionality to transition through panes of local content, even via dropdown menus.{{/i}}

    -
    - -
    -
    -

    Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.

    -
    -
    -

    Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.

    -
    - - -
    -
    {{! /example }} - - -
    - - -

    {{_i}}Usage{{/i}}

    -

    {{_i}}Enable tabbable tabs via JavaScript (each tab needs to be activated individually):{{/i}}

    -
    -$('#myTab a').click(function (e) {
    -  e.preventDefault();
    -  $(this).tab('show');
    -})
    -

    {{_i}}You can activate individual tabs in several ways:{{/i}}

    -
    -$('#myTab a[href="#profile"]').tab('show'); // Select tab by name
    -$('#myTab a:first').tab('show'); // Select first tab
    -$('#myTab a:last').tab('show'); // Select last tab
    -$('#myTab li:eq(2) a').tab('show'); // Select third tab (0-indexed)
    -
    - -

    {{_i}}Markup{{/i}}

    -

    {{_i}}You can activate a tab or pill navigation without writing any JavaScript by simply specifying data-toggle="tab" or data-toggle="pill" on an element. Adding the nav and nav-tabs classes to the tab ul will apply the Bootstrap tab styling.{{/i}}

    -
    -<ul class="nav nav-tabs">
    -  <li><a href="#home" data-toggle="tab">{{_i}}Home{{/i}}</a></li>
    -  <li><a href="#profile" data-toggle="tab">{{_i}}Profile{{/i}}</a></li>
    -  <li><a href="#messages" data-toggle="tab">{{_i}}Messages{{/i}}</a></li>
    -  <li><a href="#settings" data-toggle="tab">{{_i}}Settings{{/i}}</a></li>
    -</ul>
    - -

    {{_i}}Methods{{/i}}

    -

    $().tab

    -

    - {{_i}}Activates a tab element and content container. Tab should have either a data-target or an href targeting a container node in the DOM.{{/i}} -

    -
    -<ul class="nav nav-tabs" id="myTab">
    -  <li class="active"><a href="#home">{{_i}}Home{{/i}}</a></li>
    -  <li><a href="#profile">{{_i}}Profile{{/i}}</a></li>
    -  <li><a href="#messages">{{_i}}Messages{{/i}}</a></li>
    -  <li><a href="#settings">{{_i}}Settings{{/i}}</a></li>
    -</ul>
    -
    -<div class="tab-content">
    -  <div class="tab-pane active" id="home">...</div>
    -  <div class="tab-pane" id="profile">...</div>
    -  <div class="tab-pane" id="messages">...</div>
    -  <div class="tab-pane" id="settings">...</div>
    -</div>
    -
    -<script>
    -  $(function () {
    -    $('#myTab a:last').tab('show');
    -  })
    -</script>
    -
    - -

    {{_i}}Events{{/i}}

    - - - - - - - - - - - - - - - - - -
    {{_i}}Event{{/i}}{{_i}}Description{{/i}}
    {{_i}}show{{/i}}{{_i}}This event fires on tab show, but before the new tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.{{/i}}
    {{_i}}shown{{/i}}{{_i}}This event fires on tab show after a tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively.{{/i}}
    -
    -$('a[data-toggle="tab"]').on('shown', function (e) {
    -  e.target // activated tab
    -  e.relatedTarget // previous tab
    -})
    -
    -
    - - - -
    - - - -

    {{_i}}Examples{{/i}}

    -

    {{_i}}Inspired by the excellent jQuery.tipsy plugin written by Jason Frame; Tooltips are an updated version, which don't rely on images, use CSS3 for animations, and data-attributes for local title storage.{{/i}}

    -

    {{_i}}For performance reasons, the tooltip and popover data-apis are opt in, meaning you must initialize them yourself.{{/i}}

    -

    {{_i}}Hover over the links below to see tooltips:{{/i}}

    -
    -

    {{_i}}Tight pants next level keffiyeh you probably haven't heard of them. Photo booth beard raw denim letterpress vegan messenger bag stumptown. Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit american apparel have a terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo thundercats. Tofu biodiesel williamsburg marfa, four loko mcsweeney's cleanse vegan chambray. A really ironic artisan whatever keytar, scenester farm-to-table banksy Austin twitter handle freegan cred raw denim single-origin coffee viral.{{/i}} -

    -
    {{! /example }} - -

    {{_i}}Four directions{{/i}}

    - {{! /example }} - - -

    {{_i}}Tooltips in input groups{{/i}}

    -

    {{_i}}When using tooltips and popovers with the Bootstrap input groups, you'll have to set the container (documented below) option to avoid unwanted side effects.{{/i}}

    - -
    - - -

    {{_i}}Usage{{/i}}

    -

    {{_i}}Trigger the tooltip via JavaScript:{{/i}}

    -
    $('#example').tooltip({{_i}}options{{/i}})
    - -

    {{_i}}Options{{/i}}

    -

    {{_i}}Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-animation="".{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Name{{/i}}{{_i}}type{{/i}}{{_i}}default{{/i}}{{_i}}description{{/i}}
    {{_i}}animation{{/i}}{{_i}}boolean{{/i}}true{{_i}}apply a css fade transition to the tooltip{{/i}}
    {{_i}}html{{/i}}{{_i}}boolean{{/i}}false{{_i}}Insert html into the tooltip. If false, jquery's text method will be used to insert content into the dom. Use text if you're worried about XSS attacks.{{/i}}
    {{_i}}placement{{/i}}{{_i}}string | function{{/i}}'top'{{_i}}how to position the tooltip{{/i}} - top | bottom | left | right
    {{_i}}selector{{/i}}{{_i}}string{{/i}}false{{_i}}If a selector is provided, tooltip objects will be delegated to the specified targets.{{/i}}
    {{_i}}title{{/i}}{{_i}}string | function{{/i}}''{{_i}}default title value if `title` tag isn't present{{/i}}
    {{_i}}trigger{{/i}}{{_i}}string{{/i}}'hover focus'{{_i}}how tooltip is triggered{{/i}} - click | hover | focus | manual. {{_i}}Note you case pass trigger mutliple, space seperated, trigger types.{{/i}}
    {{_i}}delay{{/i}}{{_i}}number | object{{/i}}0 -

    {{_i}}delay showing and hiding the tooltip (ms) - does not apply to manual trigger type{{/i}}

    -

    {{_i}}If a number is supplied, delay is applied to both hide/show{{/i}}

    -

    {{_i}}Object structure is: delay: { show: 500, hide: 100 }{{/i}}

    -
    {{_i}}container{{/i}}{{_i}}string | false{{/i}}{{_i}}false{{/i}} -

    {{_i}}Appends the tooltip to a specific element container: 'body'{{/i}}

    -
    -
    - {{_i}}Heads up!{{/i}} - {{_i}}Options for individual tooltips can alternatively be specified through the use of data attributes.{{/i}} -
    - -

    {{_i}}Markup{{/i}}

    -
    <a href="#" data-toggle="tooltip" title="{{_i}}first tooltip{{/i}}">{{_i}}hover over me{{/i}}</a>
    - -

    {{_i}}Methods{{/i}}

    -

    $().tooltip({{_i}}options{{/i}})

    -

    {{_i}}Attaches a tooltip handler to an element collection.{{/i}}

    -

    .tooltip('show')

    -

    {{_i}}Reveals an element's tooltip.{{/i}}

    -
    $('#element').tooltip('show')
    -

    .tooltip('hide')

    -

    {{_i}}Hides an element's tooltip.{{/i}}

    -
    $('#element').tooltip('hide')
    -

    .tooltip('toggle')

    -

    {{_i}}Toggles an element's tooltip.{{/i}}

    -
    $('#element').tooltip('toggle')
    -

    .tooltip('destroy')

    -

    {{_i}}Hides and destroys an element's tooltip.{{/i}}

    -
    $('#element').tooltip('destroy')
    -
    - - - - -
    - - -

    {{_i}}Examples{{/i}}

    -

    {{_i}}Add small overlays of content, like those on the iPad, to any element for housing secondary information. Hover over the button to trigger the popover. Requires Tooltip to be included.{{/i}}

    - -

    {{_i}}Static popover{{/i}}

    -

    {{_i}}Four options are available: top, right, bottom, and left aligned.{{/i}}

    -
    -
    -
    -

    Popover top

    -
    -

    Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

    -
    -
    - -
    -
    -

    Popover right

    -
    -

    Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

    -
    -
    - -
    -
    -

    Popover bottom

    -
    -

    Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

    -
    -
    - -
    -
    -

    Popover left

    -
    -

    Sed posuere consectetur est at lobortis. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.

    -
    -
    - -
    -
    -

    {{_i}}No markup shown as popovers are generated from JavaScript and content within a data attribute.{{/i}}

    - -

    Live demo

    - - -

    {{_i}}Four directions{{/i}}

    - {{! /example }} - - -
    - - -

    {{_i}}Usage{{/i}}

    -

    {{_i}}Enable popovers via JavaScript:{{/i}}

    -
    $('#example').popover({{_i}}options{{/i}})
    - -

    {{_i}}Options{{/i}}

    -

    {{_i}}Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-animation="".{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Name{{/i}}{{_i}}type{{/i}}{{_i}}default{{/i}}{{_i}}description{{/i}}
    {{_i}}animation{{/i}}{{_i}}boolean{{/i}}true{{_i}}apply a css fade transition to the tooltip{{/i}}
    {{_i}}html{{/i}}{{_i}}boolean{{/i}}false{{_i}}Insert html into the popover. If false, jquery's text method will be used to insert content into the dom. Use text if you're worried about XSS attacks.{{/i}}
    {{_i}}placement{{/i}}{{_i}}string | function{{/i}}'right'{{_i}}how to position the popover{{/i}} - top | bottom | left | right
    {{_i}}selector{{/i}}{{_i}}string{{/i}}false{{_i}}if a selector is provided, tooltip objects will be delegated to the specified targets{{/i}}
    {{_i}}trigger{{/i}}{{_i}}string{{/i}}'click'{{_i}}how popover is triggered{{/i}} - click | hover | focus | manual
    {{_i}}title{{/i}}{{_i}}string | function{{/i}}''{{_i}}default title value if `title` attribute isn't present{{/i}}
    {{_i}}content{{/i}}{{_i}}string | function{{/i}}''{{_i}}default content value if `data-content` attribute isn't present{{/i}}
    {{_i}}delay{{/i}}{{_i}}number | object{{/i}}0 -

    {{_i}}delay showing and hiding the popover (ms) - does not apply to manual trigger type{{/i}}

    -

    {{_i}}If a number is supplied, delay is applied to both hide/show{{/i}}

    -

    {{_i}}Object structure is: delay: { show: 500, hide: 100 }{{/i}}

    -
    {{_i}}container{{/i}}{{_i}}string | false{{/i}}{{_i}}false{{/i}} -

    {{_i}}Appends the popover to a specific element container: 'body'{{/i}}

    -
    -
    - {{_i}}Heads up!{{/i}} - {{_i}}Options for individual popovers can alternatively be specified through the use of data attributes.{{/i}} -
    - -

    {{_i}}Markup{{/i}}

    -

    {{_i}}For performance reasons, the Tooltip and Popover data-apis are opt in. If you would like to use them just specify a selector option.{{/i}}

    - -

    {{_i}}Methods{{/i}}

    -

    $().popover({{_i}}options{{/i}})

    -

    {{_i}}Initializes popovers for an element collection.{{/i}}

    -

    .popover('show')

    -

    {{_i}}Reveals an elements popover.{{/i}}

    -
    $('#element').popover('show')
    -

    .popover('hide')

    -

    {{_i}}Hides an elements popover.{{/i}}

    -
    $('#element').popover('hide')
    -

    .popover('toggle')

    -

    {{_i}}Toggles an elements popover.{{/i}}

    -
    $('#element').popover('toggle')
    -

    .popover('destroy')

    -

    {{_i}}Hides and destroys an element's popover.{{/i}}

    -
    $('#element').popover('destroy')
    -
    - - - - -
    - - - -

    {{_i}}Example alerts{{/i}}

    -

    {{_i}}Add dismiss functionality to all alert messages with this plugin.{{/i}}

    -
    -
    - - {{_i}}Holy guacamole!{{/i}} {{_i}}Best check yo self, you're not looking too good.{{/i}} -
    -
    {{! /example }} - -
    -
    - -

    {{_i}}Oh snap! You got an error!{{/i}}

    -

    {{_i}}Change this and that and try again. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum.{{/i}}

    -

    - {{_i}}Take this action{{/i}} {{_i}}Or do this{{/i}} -

    -
    -
    {{! /example }} - - -
    - - -

    {{_i}}Usage{{/i}}

    -

    {{_i}}Enable dismissal of an alert via JavaScript:{{/i}}

    -
    $(".alert").alert()
    - -

    {{_i}}Markup{{/i}}

    -

    {{_i}}Just add data-dismiss="alert" to your close button to automatically give an alert close functionality.{{/i}}

    -
    <a class="close" data-dismiss="alert" href="#">&times;</a>
    - -

    {{_i}}Methods{{/i}}

    -

    $().alert()

    -

    {{_i}}Wraps all alerts with close functionality. To have your alerts animate out when closed, make sure they have the .fade and .in class already applied to them.{{/i}}

    -

    .alert('close')

    -

    {{_i}}Closes an alert.{{/i}}

    -
    $(".alert").alert('close')
    - - -

    {{_i}}Events{{/i}}

    -

    {{_i}}Bootstrap's alert class exposes a few events for hooking into alert functionality.{{/i}}

    - - - - - - - - - - - - - - - - - -
    {{_i}}Event{{/i}}{{_i}}Description{{/i}}
    {{_i}}close{{/i}}{{_i}}This event fires immediately when the close instance method is called.{{/i}}
    {{_i}}closed{{/i}}{{_i}}This event is fired when the alert has been closed (will wait for css transitions to complete).{{/i}}
    -
    -$('#my-alert').bind('closed', function () {
    -  // {{_i}}do something…{{/i}}
    -})
    -
    -
    - - - - -
    - - -

    {{_i}}Example uses{{/i}}

    -

    {{_i}}Do more with buttons. Control button states or create groups of buttons for more components like toolbars.{{/i}}

    - -

    {{_i}}Stateful{{/i}}

    -

    {{_i}}Add data-loading-text="Loading..." to use a loading state on a button.{{/i}}

    -
    - -
    {{! /example }} -
    <button type="button" class="btn btn-primary" data-loading-text="Loading...">Loading state</button>
    - -

    {{_i}}Single toggle{{/i}}

    -

    {{_i}}Add data-toggle="button" to activate toggling on a single button.{{/i}}

    -
    - -
    {{! /example }} -
    <button type="button" class="btn btn-primary" data-toggle="button">Single Toggle</button>
    - -

    {{_i}}Checkbox{{/i}}

    -

    {{_i}}Add data-toggle="buttons-checkbox" for checkbox style toggling on btn-group.{{/i}}

    -
    -
    - - - -
    -
    {{! /example }} -
    -<div class="btn-group" data-toggle="buttons-checkbox">
    -  <button type="button" class="btn btn-primary">Left</button>
    -  <button type="button" class="btn btn-primary">Middle</button>
    -  <button type="button" class="btn btn-primary">Right</button>
    -</div>
    -
    - -

    {{_i}}Radio{{/i}}

    -

    {{_i}}Add data-toggle="buttons-radio" for radio style toggling on btn-group.{{/i}}

    -
    -
    - - - -
    -
    {{! /example }} -
    -<div class="btn-group" data-toggle="buttons-radio">
    -  <button type="button" class="btn btn-primary">Left</button>
    -  <button type="button" class="btn btn-primary">Middle</button>
    -  <button type="button" class="btn btn-primary">Right</button>
    -</div>
    -
    - - -
    - - -

    {{_i}}Usage{{/i}}

    -

    {{_i}}Enable buttons via JavaScript:{{/i}}

    -
    $('.nav-tabs').button()
    - -

    {{_i}}Markup{{/i}}

    -

    {{_i}}Data attributes are integral to the button plugin. Check out the example code below for the various markup types.{{/i}}

    - -

    {{_i}}Options{{/i}}

    -

    {{_i}}None{{/i}}

    - -

    {{_i}}Methods{{/i}}

    -

    $().button('toggle')

    -

    {{_i}}Toggles push state. Gives the button the appearance that it has been activated.{{/i}}

    -
    - {{_i}}Heads up!{{/i}} - {{_i}}You can enable auto toggling of a button by using the data-toggle attribute.{{/i}} -
    -
    <button type="button" class="btn" data-toggle="button" >…</button>
    -

    $().button('loading')

    -

    {{_i}}Sets button state to loading - disables button and swaps text to loading text. Loading text should be defined on the button element using the data attribute data-loading-text.{{/i}} -

    -
    <button type="button" class="btn" data-loading-text="loading stuff..." >...</button>
    -
    - {{_i}}Heads up!{{/i}} - {{_i}}Firefox persists the disabled state across page loads. A workaround for this is to use autocomplete="off".{{/i}} -
    -

    $().button('reset')

    -

    {{_i}}Resets button state - swaps text to original text.{{/i}}

    -

    $().button(string)

    -

    {{_i}}Resets button state - swaps text to any data defined text state.{{/i}}

    -
    <button type="button" class="btn" data-complete-text="finished!" >...</button>
    -<script>
    -  $('.btn').button('complete')
    -</script>
    -
    -
    - - - - -
    - - -

    {{_i}}About{{/i}}

    -

    {{_i}}Get base styles and flexible support for collapsible components like accordions and navigation.{{/i}}

    -

    * {{_i}}Requires the Transitions plugin to be included.{{/i}}

    - -

    {{_i}}Example accordion{{/i}}

    -

    {{_i}}Using the collapse plugin, we built a simple accordion style widget:{{/i}}

    - -
    -
    -
    - -
    -
    - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. -
    -
    -
    -
    - -
    -
    - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. -
    -
    -
    -
    - -
    -
    - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. -
    -
    -
    -
    -
    {{! /example }} -
    -<div class="accordion" id="accordion2">
    -  <div class="accordion-group">
    -    <div class="accordion-heading">
    -      <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseOne">
    -        {{_i}}Collapsible Group Item #1{{/i}}
    -      </a>
    -    </div>
    -    <div id="collapseOne" class="accordion-body collapse in">
    -      <div class="accordion-inner">
    -        Anim pariatur cliche...
    -      </div>
    -    </div>
    -  </div>
    -  <div class="accordion-group">
    -    <div class="accordion-heading">
    -      <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseTwo">
    -        {{_i}}Collapsible Group Item #2{{/i}}
    -      </a>
    -    </div>
    -    <div id="collapseTwo" class="accordion-body collapse">
    -      <div class="accordion-inner">
    -        Anim pariatur cliche...
    -      </div>
    -    </div>
    -  </div>
    -</div>
    -...
    -
    -

    {{_i}}You can also use the plugin without the accordion markup. Make a button toggle the expanding and collapsing of another element.{{/i}}

    -
    -<button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#demo">
    -  {{_i}}simple collapsible{{/i}}
    -</button>
    -
    -<div id="demo" class="collapse in"> … </div>
    -
    - - -
    - - -

    {{_i}}Usage{{/i}}

    - -

    {{_i}}Via data attributes{{/i}}

    -

    {{_i}}Just add data-toggle="collapse" and a data-target to element to automatically assign control of a collapsible element. The data-target attribute accepts a css selector to apply the collapse to. Be sure to add the class collapse to the collapsible element. If you'd like it to default open, add the additional class in.{{/i}}

    -

    {{_i}}To add accordion-like group management to a collapsible control, add the data attribute data-parent="#selector". Refer to the demo to see this in action.{{/i}}

    - -

    {{_i}}Via JavaScript{{/i}}

    -

    {{_i}}Enable manually with:{{/i}}

    -
    $(".collapse").collapse()
    - -

    {{_i}}Options{{/i}}

    -

    {{_i}}Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-parent="".{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Name{{/i}}{{_i}}type{{/i}}{{_i}}default{{/i}}{{_i}}description{{/i}}
    {{_i}}parent{{/i}}{{_i}}selector{{/i}}false{{_i}}If selector then all collapsible elements under the specified parent will be closed when this collapsible item is shown. (similar to traditional accordion behavior){{/i}}
    {{_i}}toggle{{/i}}{{_i}}boolean{{/i}}true{{_i}}Toggles the collapsible element on invocation{{/i}}
    - - -

    {{_i}}Methods{{/i}}

    -

    .collapse({{_i}}options{{/i}})

    -

    {{_i}}Activates your content as a collapsible element. Accepts an optional options object.{{/i}} -

    -$('#myCollapsible').collapse({
    -  toggle: false
    -})
    -
    -

    .collapse('toggle')

    -

    {{_i}}Toggles a collapsible element to shown or hidden.{{/i}}

    -

    .collapse('show')

    -

    {{_i}}Shows a collapsible element.{{/i}}

    -

    .collapse('hide')

    -

    {{_i}}Hides a collapsible element.{{/i}}

    - -

    {{_i}}Events{{/i}}

    -

    {{_i}}Bootstrap's collapse class exposes a few events for hooking into collapse functionality.{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Event{{/i}}{{_i}}Description{{/i}}
    {{_i}}show{{/i}}{{_i}}This event fires immediately when the show instance method is called.{{/i}}
    {{_i}}shown{{/i}}{{_i}}This event is fired when a collapse element has been made visible to the user (will wait for css transitions to complete).{{/i}}
    {{_i}}hide{{/i}} - {{_i}}This event is fired immediately when the hide method has been called.{{/i}} -
    {{_i}}hidden{{/i}}{{_i}}This event is fired when a collapse element has been hidden from the user (will wait for css transitions to complete).{{/i}}
    -
    -$('#myCollapsible').on('hidden', function () {
    -  // {{_i}}do something…{{/i}}
    -})
    -
    - - - - - - - - - -
    - - - -

    {{_i}}Example{{/i}}

    -

    {{_i}}A basic, easily extended plugin for quickly creating elegant typeaheads with any form text input.{{/i}}

    -
    - -
    {{! /example }} -
    <input type="text" data-provide="typeahead">
    -

    You'll want to set autocomplete="off" to prevent default browser menus from appearing over the Bootstrap typeahead dropdown.

    - -
    - - -

    {{_i}}Usage{{/i}}

    - -

    {{_i}}Via data attributes{{/i}}

    -

    {{_i}}Add data attributes to register an element with typeahead functionality as shown in the example above.{{/i}}

    - -

    {{_i}}Via JavaScript{{/i}}

    -

    {{_i}}Call the typeahead manually with:{{/i}}

    -
    $('.typeahead').typeahead()
    - -

    {{_i}}Options{{/i}}

    -

    {{_i}}Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-source="".{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Name{{/i}}{{_i}}type{{/i}}{{_i}}default{{/i}}{{_i}}description{{/i}}
    {{_i}}source{{/i}}{{_i}}array, function{{/i}}[ ]{{_i}}The data source to query against. May be an array of strings or a function. The function is passed two arguments, the query value in the input field and the process callback. The function may be used synchronously by returning the data source directly or asynchronously via the process callback's single argument.{{/i}}
    {{_i}}items{{/i}}{{_i}}number{{/i}}8{{_i}}The max number of items to display in the dropdown.{{/i}}
    {{_i}}minLength{{/i}}{{_i}}number{{/i}}{{_i}}1{{/i}}{{_i}}The minimum character length needed before triggering autocomplete suggestions{{/i}}
    {{_i}}matcher{{/i}}{{_i}}function{{/i}}{{_i}}case insensitive{{/i}}{{_i}}The method used to determine if a query matches an item. Accepts a single argument, the item against which to test the query. Access the current query with this.query. Return a boolean true if query is a match.{{/i}}
    {{_i}}sorter{{/i}}{{_i}}function{{/i}}{{_i}}exact match,
    case sensitive,
    case insensitive{{/i}}
    {{_i}}Method used to sort autocomplete results. Accepts a single argument items and has the scope of the typeahead instance. Reference the current query with this.query.{{/i}}
    {{_i}}updater{{/i}}{{_i}}function{{/i}}{{_i}}returns selected item{{/i}}{{_i}}The method used to return selected item. Accepts a single argument, the item and has the scope of the typeahead instance.{{/i}}
    {{_i}}highlighter{{/i}}{{_i}}function{{/i}}{{_i}}highlights all default matches{{/i}}{{_i}}Method used to highlight autocomplete results. Accepts a single argument item and has the scope of the typeahead instance. Should return html.{{/i}}
    - -

    {{_i}}Methods{{/i}}

    -

    .typeahead({{_i}}options{{/i}})

    -

    {{_i}}Initializes an input with a typeahead.{{/i}}

    -
    - - - - -
    - - -

    {{_i}}Example{{/i}}

    -

    {{_i}}The subnavigation on the left is a live demo of the affix plugin.{{/i}}

    - -
    - -

    {{_i}}Usage{{/i}}

    - -

    {{_i}}Via data attributes{{/i}}

    -

    {{_i}}To easily add affix behavior to any element, just add data-spy="affix" to the element you want to spy on. Then use offsets to define when to toggle the pinning of an element on and off.{{/i}}

    - -
    <div data-spy="affix" data-offset-top="200">...</div>
    - -
    - {{_i}}Heads up!{{/i}} - {{_i}}You must manage the position of a pinned element and the behavior of its immediate parent. Position is controlled by affix, affix-top, and affix-bottom. Remember to check for a potentially collapsed parent when the affix kicks in as it's removing content from the normal flow of the page.{{/i}} -
    - -

    {{_i}}Via JavaScript{{/i}}

    -

    {{_i}}Call the affix plugin via JavaScript:{{/i}}

    -
    $('#navbar').affix()
    - -

    {{_i}}Options{{/i}}

    -

    {{_i}}Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-offset-top="200".{{/i}}

    - - - - - - - - - - - - - - - - - -
    {{_i}}Name{{/i}}{{_i}}type{{/i}}{{_i}}default{{/i}}{{_i}}description{{/i}}
    {{_i}}offset{{/i}}{{_i}}number | function | object{{/i}}{{_i}}10{{/i}}{{_i}}Pixels to offset from screen when calculating position of scroll. If a single number is provided, the offset will be applied in both top and left directions. To listen for a single direction, or multiple unique offsets, just provide an object offset: { x: 10 }. Use a function when you need to dynamically provide an offset (useful for some responsive designs).{{/i}}
    -
    - - - -
    {{! /span9 }} -
    {{! row}} - -
    {{! /.container }} diff --git a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/scaffolding.mustache b/src/main/webapp/bower_components/bootstrap/docs/templates/pages/scaffolding.mustache deleted file mode 100644 index a6f2f9dac..000000000 --- a/src/main/webapp/bower_components/bootstrap/docs/templates/pages/scaffolding.mustache +++ /dev/null @@ -1,485 +0,0 @@ - -
    -
    -

    {{_i}}Scaffolding{{/i}}

    -

    {{_i}}Bootstrap is built on responsive 12-column grids, layouts, and components.{{/i}}

    -
    -
    - -
    - - -
    - -
    - - - - -
    - - -

    {{_i}}Requires HTML5 doctype{{/i}}

    -

    {{_i}}Bootstrap makes use of certain HTML elements and CSS properties that require the use of the HTML5 doctype. Include it at the beginning of all your projects.{{/i}}

    -
    -<!DOCTYPE html>
    -<html lang="en">
    -  ...
    -</html>
    -
    - -

    {{_i}}Typography and links{{/i}}

    -

    {{_i}}Bootstrap sets basic global display, typography, and link styles. Specifically, we:{{/i}}

    -
      -
    • {{_i}}Remove margin on the body{{/i}}
    • -
    • {{_i}}Set background-color: white; on the body{{/i}}
    • -
    • {{_i}}Use the @baseFontFamily, @baseFontSize, and @baseLineHeight attributes as our typographic base{{/i}}
    • -
    • {{_i}}Set the global link color via @linkColor and apply link underlines only on :hover{{/i}}
    • -
    -

    {{_i}}These styles can be found within scaffolding.less.{{/i}}

    - -

    {{_i}}Reset via Normalize{{/i}}

    -

    {{_i}}With Bootstrap 2, the old reset block has been dropped in favor of Normalize.css, a project by Nicolas Gallagher and Jonathan Neal that also powers the HTML5 Boilerplate. While we use much of Normalize within our reset.less, we have removed some elements specifically for Bootstrap.{{/i}}

    - -
    - - - - - -
    - - -

    {{_i}}Live grid example{{/i}}

    -

    {{_i}}The default Bootstrap grid system utilizes 12 columns, making for a 940px wide container without responsive features enabled. With the responsive CSS file added, the grid adapts to be 724px and 1170px wide depending on your viewport. Below 767px viewports, the columns become fluid and stack vertically.{{/i}}

    -
    -
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    -
    -
    2
    -
    3
    -
    4
    -
    -
    -
    4
    -
    5
    -
    -
    -
    9
    -
    -
    - -

    {{_i}}Basic grid HTML{{/i}}

    -

    {{_i}}For a simple two column layout, create a .row and add the appropriate number of .span* columns. As this is a 12-column grid, each .span* spans a number of those 12 columns, and should always add up to 12 for each row (or the number of columns in the parent).{{/i}}

    -
    -<div class="row">
    -  <div class="span4">...</div>
    -  <div class="span8">...</div>
    -</div>
    -
    -

    {{_i}}Given this example, we have .span4 and .span8, making for 12 total columns and a complete row.{{/i}}

    - -

    {{_i}}Offsetting columns{{/i}}

    -

    {{_i}}Move columns to the right using .offset* classes. Each class increases the left margin of a column by a whole column. For example, .offset4 moves .span4 over four columns.{{/i}}

    -
    -
    -
    4
    -
    3 offset 2
    -
    -
    -
    3 offset 1
    -
    3 offset 2
    -
    -
    -
    6 offset 3
    -
    -
    -
    -<div class="row">
    -  <div class="span4">...</div>
    -  <div class="span3 offset2">...</div>
    -</div>
    -
    - -

    {{_i}}Nesting columns{{/i}}

    -

    {{_i}}To nest your content with the default grid, add a new .row and set of .span* columns within an existing .span* column. Nested rows should include a set of columns that add up to the number of columns of its parent.{{/i}}

    -
    -
    - {{_i}}Level 1 column{{/i}} -
    -
    - {{_i}}Level 2{{/i}} -
    -
    - {{_i}}Level 2{{/i}} -
    -
    -
    -
    -
    -<div class="row">
    -  <div class="span9">
    -    {{_i}}Level 1 column{{/i}}
    -    <div class="row">
    -      <div class="span6">{{_i}}Level 2{{/i}}</div>
    -      <div class="span3">{{_i}}Level 2{{/i}}</div>
    -    </div>
    -  </div>
    -</div>
    -
    -
    - - - - -
    - - -

    {{_i}}Live fluid grid example{{/i}}

    -

    {{_i}}The fluid grid system uses percents instead of pixels for column widths. It has the same responsive capabilities as our fixed grid system, ensuring proper proportions for key screen resolutions and devices.{{/i}}

    -
    -
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    1
    -
    -
    -
    4
    -
    4
    -
    4
    -
    -
    -
    4
    -
    8
    -
    -
    -
    6
    -
    6
    -
    -
    -
    12
    -
    -
    - -

    {{_i}}Basic fluid grid HTML{{/i}}

    -

    {{_i}}Make any row "fluid" by changing .row to .row-fluid. The column classes stay the exact same, making it easy to flip between fixed and fluid grids.{{/i}}

    -
    -<div class="row-fluid">
    -  <div class="span4">...</div>
    -  <div class="span8">...</div>
    -</div>
    -
    - -

    {{_i}}Fluid offsetting{{/i}}

    -

    {{_i}}Operates the same way as the fixed grid system offsetting: add .offset* to any column to offset by that many columns.{{/i}}

    -
    -
    -
    4
    -
    4 offset 4
    -
    -
    -
    3 offset 3
    -
    3 offset 3
    -
    -
    -
    6 offset 6
    -
    -
    -
    -<div class="row-fluid">
    -  <div class="span4">...</div>
    -  <div class="span4 offset2">...</div>
    -</div>
    -
    - -

    {{_i}}Fluid nesting{{/i}}

    -

    {{_i}}Fluid grids utilize nesting differently: each nested level of columns should add up to 12 columns. This is because the fluid grid uses percentages, not pixels, for setting widths.{{/i}}

    -
    -
    - {{_i}}Fluid 12{{/i}} -
    -
    - {{_i}}Fluid 6{{/i}} -
    -
    - {{_i}}Fluid 6{{/i}} -
    -
    - {{_i}}Fluid 6{{/i}} -
    -
    -
    -
    - {{_i}}Fluid 6{{/i}} -
    -
    -
    -
    -
    -<div class="row-fluid">
    -  <div class="span12">
    -    {{_i}}Fluid 12{{/i}}
    -    <div class="row-fluid">
    -      <div class="span6">
    -        {{_i}}Fluid 6{{/i}}
    -        <div class="row-fluid">
    -          <div class="span6">{{_i}}Fluid 6{{/i}}</div>
    -          <div class="span6">{{_i}}Fluid 6{{/i}}</div>
    -        </div>
    -      </div>
    -      <div class="span6">{{_i}}Fluid 6{{/i}}</div>
    -    </div>
    -  </div>
    -</div>
    -
    - -
    - - - - - -
    - - -

    {{_i}}Fixed layout{{/i}}

    -

    {{_i}}Provides a common fixed-width (and optionally responsive) layout with only <div class="container"> required.{{/i}}

    -
    -
    -
    -
    -<body>
    -  <div class="container">
    -    ...
    -  </div>
    -</body>
    -
    - -

    {{_i}}Fluid layout{{/i}}

    -

    {{_i}}Create a fluid, two-column page with <div class="container-fluid">—great for applications and docs.{{/i}}

    -
    -
    -
    -
    -
    -<div class="container-fluid">
    -  <div class="row-fluid">
    -    <div class="span2">
    -      <!--{{_i}}Sidebar content{{/i}}-->
    -    </div>
    -    <div class="span10">
    -      <!--{{_i}}Body content{{/i}}-->
    -    </div>
    -  </div>
    -</div>
    -
    -
    - - - - - -
    - - - {{! Enabling }} -

    {{_i}}Enabling responsive features{{/i}}

    -

    {{_i}}Turn on responsive CSS in your project by including the proper meta tag and additional stylesheet within the <head> of your document. If you've compiled Bootstrap from the Customize page, you need only include the meta tag.{{/i}}

    -
    -<meta name="viewport" content="width=device-width, initial-scale=1.0">
    -<link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
    -
    -

    {{_i}}Heads up!{{/i}} {{_i}} Bootstrap doesn't include responsive features by default at this time as not everything needs to be responsive. Instead of encouraging developers to remove this feature, we figure it best to enable it as needed.{{/i}}

    - - {{! About }} -

    {{_i}}About responsive Bootstrap{{/i}}

    - Responsive devices -

    {{_i}}Media queries allow for custom CSS based on a number of conditions—ratios, widths, display type, etc—but usually focuses around min-width and max-width.{{/i}}

    -
      -
    • {{_i}}Modify the width of column in our grid{{/i}}
    • -
    • {{_i}}Stack elements instead of float wherever necessary{{/i}}
    • -
    • {{_i}}Resize headings and text to be more appropriate for devices{{/i}}
    • -
    -

    {{_i}}Use media queries responsibly and only as a start to your mobile audiences. For larger projects, do consider dedicated code bases and not layers of media queries.{{/i}}

    - - {{! Supported }} -

    {{_i}}Supported devices{{/i}}

    -

    {{_i}}Bootstrap supports a handful of media queries in a single file to help make your projects more appropriate on different devices and screen resolutions. Here's what's included:{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Label{{/i}}{{_i}}Layout width{{/i}}{{_i}}Column width{{/i}}{{_i}}Gutter width{{/i}}
    {{_i}}Large display{{/i}}1200px and up70px30px
    {{_i}}Default{{/i}}980px and up60px20px
    {{_i}}Portrait tablets{{/i}}768px and above42px20px
    {{_i}}Phones to tablets{{/i}}767px and below{{_i}}Fluid columns, no fixed widths{{/i}}
    {{_i}}Phones{{/i}}480px and below{{_i}}Fluid columns, no fixed widths{{/i}}
    -
    -/* {{_i}}Large desktop{{/i}} */
    -@media (min-width: 1200px) { ... }
    -
    -/* {{_i}}Portrait tablet to landscape and desktop{{/i}} */
    -@media (min-width: 768px) and (max-width: 979px) { ... }
    -
    -/* {{_i}}Landscape phone to portrait tablet{{/i}} */
    -@media (max-width: 767px) { ... }
    -
    -/* {{_i}}Landscape phones and down{{/i}} */
    -@media (max-width: 480px) { ... }
    -
    - - - {{! Responsive utility classes }} -

    {{_i}}Responsive utility classes{{/i}}

    -

    {{_i}}For faster mobile-friendly development, use these utility classes for showing and hiding content by device. Below is a table of the available classes and their effect on a given media query layout (labeled by device). They can be found in responsive.less.{{/i}}

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    {{_i}}Class{{/i}}{{_i}}Phones 767px and below{{/i}}{{_i}}Tablets 979px to 768px{{/i}}{{_i}}Desktops Default{{/i}}
    .visible-phone{{_i}}Visible{{/i}}
    .visible-tablet{{_i}}Visible{{/i}}
    .visible-desktop{{_i}}Visible{{/i}}
    .hidden-phone{{_i}}Visible{{/i}}{{_i}}Visible{{/i}}
    .hidden-tablet{{_i}}Visible{{/i}}{{_i}}Visible{{/i}}
    .hidden-desktop{{_i}}Visible{{/i}}{{_i}}Visible{{/i}}
    - -

    {{_i}}When to use{{/i}}

    -

    {{_i}}Use on a limited basis and avoid creating entirely different versions of the same site. Instead, use them to complement each device's presentation. Responsive utilities should not be used with tables, and as such are not supported.{{/i}}

    - -

    {{_i}}Responsive utilities test case{{/i}}

    -

    {{_i}}Resize your browser or load on different devices to test the above classes.{{/i}}

    -

    {{_i}}Visible on...{{/i}}

    -

    {{_i}}Green checkmarks indicate that class is visible in your current viewport.{{/i}}

    -
      -
    • {{_i}}Phone{{/i}}✔ {{_i}}Phone{{/i}}
    • -
    • {{_i}}Tablet{{/i}}✔ {{_i}}Tablet{{/i}}
    • -
    • {{_i}}Desktop{{/i}}✔ {{_i}}Desktop{{/i}}
    • -
    -

    {{_i}}Hidden on...{{/i}}

    -

    {{_i}}Here, green checkmarks indicate that class is hidden in your current viewport.{{/i}}

    -
      -
    • {{_i}}Phone{{/i}}✔ {{_i}}Phone{{/i}}
    • -
    • {{_i}}Tablet{{/i}}✔ {{_i}}Tablet{{/i}}
    • -
    • {{_i}}Desktop{{/i}}✔ {{_i}}Desktop{{/i}}
    • -
    - -
    - - - -
    {{! /span9 }} -
    {{! row}} - -
    {{! /.container }} diff --git a/src/main/webapp/bower_components/bootstrap/img/glyphicons-halflings-white.png b/src/main/webapp/bower_components/bootstrap/img/glyphicons-halflings-white.png deleted file mode 100644 index 3bf6484a29d8da269f9bc874b25493a45fae3bae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8777 zcmZvC1yGz#v+m*$LXcp=A$ZWB0fL7wNbp_U*$~{_gL`my3oP#L!5tQYy99Ta`+g_q zKlj|KJ2f@c)ARJx{q*bbkhN_!|Wn*Vos8{TEhUT@5e;_WJsIMMcG5%>DiS&dv_N`4@J0cnAQ-#>RjZ z00W5t&tJ^l-QC*ST1-p~00u^9XJ=AUl7oW-;2a+x2k__T=grN{+1c4XK0ZL~^z^i$ zp&>vEhr@4fZWb380S18T&!0cQ3IKpHF)?v=b_NIm0Q>vwY7D0baZ)n z31Fa5sELUQARIVaU0nqf0XzT+fB_63aA;@<$l~wse|mcA;^G1TmX?-)e)jkGPfkuA z92@|!<>h5S_4f8QP-JRq>d&7)^Yin8l7K8gED$&_FaV?gY+wLjpoW%~7NDe=nHfMG z5DO3j{R9kv5GbssrUpO)OyvVrlx>u0UKD0i;Dpm5S5dY16(DL5l{ixz|mhJU@&-OWCTb7_%}8-fE(P~+XIRO zJU|wp1|S>|J3KrLcz^+v1f&BDpd>&MAaibR4#5A_4(MucZwG9E1h4@u0P@C8;oo+g zIVj7kfJi{oV~E(NZ*h(@^-(Q(C`Psb3KZ{N;^GB(a8NE*Vwc715!9 zr-H4Ao|T_c6+VT_JH9H+P3>iXSt!a$F`>s`jn`w9GZ_~B!{0soaiV|O_c^R2aWa%}O3jUE)WO=pa zs~_Wz08z|ieY5A%$@FcBF9^!1a}m5ks@7gjn;67N>}S~Hrm`4sM5Hh`q7&5-N{|31 z6x1{ol7BnskoViZ0GqbLa#kW`Z)VCjt1MysKg|rT zi!?s##Ck>8c zpi|>$lGlw#@yMNi&V4`6OBGJ(H&7lqLlcTQ&1zWriG_fL>BnFcr~?;E93{M-xIozQ zO=EHQ#+?<}%@wbWWv23#!V70h9MOuUVaU>3kpTvYfc|LBw?&b*89~Gc9i&8tlT#kF ztpbZoAzkdB+UTy=tx%L3Z4)I{zY(Kb)eg{InobSJmNwPZt$14aS-uc4eKuY8h$dtfyxu^a%zA)>fYI&)@ZXky?^{5>xSC?;w4r&td6vBdi%vHm4=XJH!3yL3?Ep+T5aU_>i;yr_XGq zxZfCzUU@GvnoIk+_Nd`aky>S&H!b*{A%L>?*XPAgWL(Vf(k7qUS}>Zn=U(ZfcOc{B z3*tOHH@t5Ub5D~#N7!Fxx}P2)sy{vE_l(R7$aW&CX>c|&HY+7};vUIietK%}!phrCuh+;C@1usp;XLU<8Gq8P!rEI3ieg#W$!= zQcZr{hp>8sF?k&Yl0?B84OneiQxef-4TEFrq3O~JAZR}yEJHA|Xkqd49tR&8oq{zP zY@>J^HBV*(gJvJZc_0VFN7Sx?H7#75E3#?N8Z!C+_f53YU}pyggxx1?wQi5Yb-_`I`_V*SMx5+*P^b=ec5RON-k1cIlsBLk}(HiaJyab0`CI zo0{=1_LO$~oE2%Tl_}KURuX<`+mQN_sTdM&* zkFf!Xtl^e^gTy6ON=&gTn6)$JHQq2)33R@_!#9?BLNq-Wi{U|rVX7Vny$l6#+SZ@KvQt@VYb%<9JfapI^b9j=wa+Tqb4ei;8c5 z&1>Uz@lVFv6T4Z*YU$r4G`g=91lSeA<=GRZ!*KTWKDPR}NPUW%peCUj`Ix_LDq!8| zMH-V`Pv!a~QkTL||L@cqiTz)*G-0=ytr1KqTuFPan9y4gYD5>PleK`NZB$ev@W%t= zkp)_=lBUTLZJpAtZg;pjI;7r2y|26-N7&a(hX|`1YNM9N8{>8JAuv}hp1v`3JHT-=5lbXpbMq7X~2J5Kl zh7tyU`_AusMFZ{ej9D;Uyy;SQ!4nwgSnngsYBwdS&EO3NS*o04)*juAYl;57c2Ly0(DEZ8IY?zSph-kyxu+D`tt@oU{32J#I{vmy=#0ySPK zA+i(A3yl)qmTz*$dZi#y9FS;$;h%bY+;StNx{_R56Otq+?pGe^T^{5d7Gs&?`_r`8 zD&dzOA|j8@3A&FR5U3*eQNBf<4^4W_iS_()*8b4aaUzfk2 zzIcMWSEjm;EPZPk{j{1>oXd}pXAj!NaRm8{Sjz!D=~q3WJ@vmt6ND_?HI~|wUS1j5 z9!S1MKr7%nxoJ3k`GB^7yV~*{n~O~n6($~x5Bu{7s|JyXbAyKI4+tO(zZYMslK;Zc zzeHGVl{`iP@jfSKq>R;{+djJ9n%$%EL()Uw+sykjNQdflkJZSjqV_QDWivbZS~S{K zkE@T^Jcv)Dfm93!mf$XYnCT--_A$zo9MOkPB6&diM8MwOfV?+ApNv`moV@nqn>&lv zYbN1-M|jc~sG|yLN^1R2=`+1ih3jCshg`iP&mY$GMTcY^W^T`WOCX!{-KHmZ#GiRH zYl{|+KLn5!PCLtBy~9i}`#d^gCDDx$+GQb~uc;V#K3OgbbOG0j5{BRG-si%Bo{@lB zGIt+Ain8^C`!*S0d0OSWVO+Z89}}O8aFTZ>p&k}2gGCV zh#<$gswePFxWGT$4DC^8@84_e*^KT74?7n8!$8cg=sL$OlKr&HMh@Rr5%*Wr!xoOl zo7jItnj-xYgVTX)H1=A2bD(tleEH57#V{xAeW_ezISg5OC zg=k>hOLA^urTH_e6*vSYRqCm$J{xo}-x3@HH;bsHD1Z`Pzvsn}%cvfw%Q(}h`Dgtb z0_J^niUmoCM5$*f)6}}qi(u;cPgxfyeVaaVmOsG<)5`6tzU4wyhF;k|~|x>7-2hXpVBpc5k{L4M`Wbe6Q?tr^*B z`Y*>6*&R#~%JlBIitlZ^qGe3s21~h3U|&k%%jeMM;6!~UH|+0+<5V-_zDqZQN79?n?!Aj!Nj`YMO9?j>uqI9-Tex+nJD z%e0#Yca6(zqGUR|KITa?9x-#C0!JKJHO(+fy@1!B$%ZwJwncQW7vGYv?~!^`#L~Um zOL++>4qmqW`0Chc0T23G8|vO)tK=Z2`gvS4*qpqhIJCEv9i&&$09VO8YOz|oZ+ubd zNXVdLc&p=KsSgtmIPLN69P7xYkYQ1vJ?u1g)T!6Ru`k2wkdj*wDC)VryGu2=yb0?F z>q~~e>KZ0d_#7f3UgV%9MY1}vMgF{B8yfE{HL*pMyhYF)WDZ^^3vS8F zGlOhs%g_~pS3=WQ#494@jAXwOtr^Y|TnQ5zki>qRG)(oPY*f}U_=ip_{qB0!%w7~G zWE!P4p3khyW-JJnE>eECuYfI?^d366Shq!Wm#x&jAo>=HdCllE$>DPO0N;y#4G)D2y#B@5=N=+F%Xo2n{gKcPcK2!hP*^WSXl+ut; zyLvVoY>VL{H%Kd9^i~lsb8j4>$EllrparEOJNT?Ym>vJa$(P^tOG)5aVb_5w^*&M0 zYOJ`I`}9}UoSnYg#E(&yyK(tqr^@n}qU2H2DhkK-`2He% zgXr_4kpXoQHxAO9S`wEdmqGU4j=1JdG!OixdqB4PPP6RXA}>GM zumruUUH|ZG2$bBj)Qluj&uB=dRb)?^qomw?Z$X%#D+Q*O97eHrgVB2*mR$bFBU`*} zIem?dM)i}raTFDn@5^caxE^XFXVhBePmH9fqcTi`TLaXiueH=@06sl}>F%}h9H_e9 z>^O?LxM1EjX}NVppaO@NNQr=AtHcH-BU{yBT_vejJ#J)l^cl69Z7$sk`82Zyw7Wxt z=~J?hZm{f@W}|96FUJfy65Gk8?^{^yjhOahUMCNNpt5DJw}ZKH7b!bGiFY9y6OY&T z_N)?Jj(MuLTN36ZCJ6I5Xy7uVlrb$o*Z%=-)kPo9s?<^Yqz~!Z* z_mP8(unFq65XSi!$@YtieSQ!<7IEOaA9VkKI?lA`*(nURvfKL8cX}-+~uw9|_5)uC2`ZHcaeX7L8aG6Ghleg@F9aG%X$#g6^yP5apnB>YTz&EfS{q z9UVfSyEIczebC)qlVu5cOoMzS_jrC|)rQlAzK7sfiW0`M8mVIohazPE9Jzn*qPt%6 zZL8RELY@L09B83@Be;x5V-IHnn$}{RAT#<2JA%ttlk#^(%u}CGze|1JY5MPhbfnYG zIw%$XfBmA-<_pKLpGKwbRF$#P;@_)ech#>vj25sv25VM$ouo)?BXdRcO{)*OwTw)G zv43W~T6ekBMtUD%5Bm>`^Ltv!w4~65N!Ut5twl!Agrzyq4O2Fi3pUMtCU~>9gt_=h-f% z;1&OuSu?A_sJvIvQ+dZNo3?m1%b1+s&UAx?8sUHEe_sB7zkm4R%6)<@oYB_i5>3Ip zIA+?jVdX|zL{)?TGpx+=Ta>G80}0}Ax+722$XFNJsC1gcH56{8B)*)eU#r~HrC&}` z|EWW92&;6y;3}!L5zXa385@?-D%>dSvyK;?jqU2t_R3wvBW;$!j45uQ7tyEIQva;Db}r&bR3kqNSh)Q_$MJ#Uj3Gj1F;)sO|%6z#@<+ zi{pbYsYS#u`X$Nf($OS+lhw>xgjos1OnF^$-I$u;qhJswhH~p|ab*nO>zBrtb0ndn zxV0uh!LN`&xckTP+JW}gznSpU492)u+`f{9Yr)js`NmfYH#Wdtradc0TnKNz@Su!e zu$9}G_=ku;%4xk}eXl>)KgpuT>_<`Ud(A^a++K&pm3LbN;gI}ku@YVrA%FJBZ5$;m zobR8}OLtW4-i+qPPLS-(7<>M{)rhiPoi@?&vDeVq5%fmZk=mDdRV>Pb-l7pP1y6|J z8I>sF+TypKV=_^NwBU^>4JJq<*14GLfM2*XQzYdlqqjnE)gZsPW^E@mp&ww* zW9i>XL=uwLVZ9pO*8K>t>vdL~Ek_NUL$?LQi5sc#1Q-f6-ywKcIT8Kw?C(_3pbR`e|)%9S-({if|E+hR2W!&qfQ&UiF^I!|M#xhdWsenv^wpKCBiuxXbnp85`{i|;BM?Ba`lqTA zyRm=UWJl&E{8JzYDHFu>*Z10-?#A8D|5jW9Ho0*CAs0fAy~MqbwYuOq9jjt9*nuHI zbDwKvh)5Ir$r!fS5|;?Dt>V+@F*v8=TJJF)TdnC#Mk>+tGDGCw;A~^PC`gUt*<(|i zB{{g{`uFehu`$fm4)&k7`u{xIV)yvA(%5SxX9MS80p2EKnLtCZ>tlX>*Z6nd&6-Mv$5rHD*db;&IBK3KH&M<+ArlGXDRdX1VVO4)&R$f4NxXI>GBh zSv|h>5GDAI(4E`@F?EnW zS>#c&Gw6~_XL`qQG4bK`W*>hek4LX*efn6|_MY+rXkNyAuu?NxS%L7~9tD3cn7&p( zCtfqe6sjB&Q-Vs7BP5+%;#Gk};4xtwU!KY0XXbmkUy$kR9)!~?*v)qw00!+Yg^#H> zc#8*z6zZo>+(bud?K<*!QO4ehiTCK&PD4G&n)Tr9X_3r-we z?fI+}-G~Yn93gI6F{}Dw_SC*FLZ)5(85zp4%uubtD)J)UELLkvGk4#tw&Tussa)mTD$R2&O~{ zCI3>fr-!-b@EGRI%g0L8UU%%u_<;e9439JNV;4KSxd|78v+I+8^rmMf3f40Jb}wEszROD?xBZu>Ll3;sUIoNxDK3|j3*sam2tC@@e$ z^!;+AK>efeBJB%ALsQ{uFui)oDoq()2USi?n=6C3#eetz?wPswc={I<8x=(8lE4EIsUfyGNZ{|KYn1IR|=E==f z(;!A5(-2y^2xRFCSPqzHAZn5RCN_bp22T(KEtjA(rFZ%>a4@STrHZflxKoqe9Z4@^ zM*scx_y73?Q{vt6?~WEl?2q*;@8 z3M*&@%l)SQmXkcUm)d@GT2#JdzhfSAP9|n#C;$E8X|pwD!r#X?0P>0ZisQ~TNqupW z*lUY~+ikD`vQb?@SAWX#r*Y+;=_|oacL$2CL$^(mV}aKO77pg}O+-=T1oLBT5sL2i z42Qth2+0@C`c+*D0*5!qy26sis<9a7>LN2{z%Qj49t z=L@x`4$ALHb*3COHoT?5S_c(Hs}g!V>W^=6Q0}zaubkDn)(lTax0+!+%B}9Vqw6{H zvL|BRM`O<@;eVi1DzM!tXtBrA20Ce@^Jz|>%X-t`vi-%WweXCh_LhI#bUg2*pcP~R z*RuTUzBKLXO~~uMd&o$v3@d0shHfUjC6c539PE6rF&;Ufa(Rw@K1*m7?f5)t`MjH0 z)_V(cajV5Am>f!kWcI@5rE8t6$S>5M=k=aRZROH6fA^jJp~2NlR4;Q2>L$7F#RT#9 z>4@1RhWG`Khy>P2j1Yx^BBL{S`niMaxlSWV-JBU0-T9zZ%>7mR3l$~QV$({o0;jTI ze5=cN^!Bc2bT|BcojXp~K#2cM>OTe*cM{Kg-j*CkiW)EGQot^}s;cy8_1_@JA0Whq zlrNr+R;Efa+`6N)s5rH*|E)nYZ3uqkk2C(E7@A|3YI`ozP~9Lexx#*1(r8luq+YPk z{J}c$s` zPM35Fx(YWB3Z5IYnN+L_4|jaR(5iWJi2~l&xy}aU7kW?o-V*6Av2wyZTG!E2KSW2* zGRLQkQU;Oz##ie-Z4fI)WSRxn$(ZcD;TL+;^r=a4(G~H3ZhK$lSXZj?cvyY8%d9JM zzc3#pD^W_QnWy#rx#;c&N@sqHhrnHRmj#i;s%zLm6SE(n&BWpd&f7>XnjV}OlZntI70fq%8~9<7 zMYaw`E-rp49-oC1N_uZTo)Cu%RR2QWdHpzQIcNsoDp`3xfP+`gI?tVQZ4X={qU?(n zV>0ASES^Xuc;9JBji{)RnFL(Lez;8XbB1uWaMp@p?7xhXk6V#!6B@aP4Rz7-K%a>i z?fvf}va_DGUXlI#4--`A3qK7J?-HwnG7O~H2;zR~RLW)_^#La!=}+>KW#anZ{|^D3 B7G?kd diff --git a/src/main/webapp/bower_components/bootstrap/img/glyphicons-halflings.png b/src/main/webapp/bower_components/bootstrap/img/glyphicons-halflings.png deleted file mode 100644 index a9969993201f9cee63cf9f49217646347297b643..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12799 zcma*OWmH^Ivn@*S;K3nSf_t!#;0f+&pm7Po8`nk}2q8f5;M%x$SdAkd9FAvlc$ zx660V9e3Ox@4WZ^?7jZ%QFGU-T~%||Ug4iK6bbQY@zBuF2$hxOw9wF=A)nUSxR_5@ zEX>HBryGrjyuOFFv$Y4<+|3H@gQfEqD<)+}a~mryD|1U9*I_FOG&F%+Ww{SJ-V2BR zjt<81Ek$}Yb*95D4RS0HCps|uLyovt;P05hchQb-u2bzLtmog&f2}1VlNhxXV);S9 zM2buBg~!q9PtF)&KGRgf3#z7B(hm5WlNClaCWFs!-P!4-u*u5+=+D|ZE9e`KvhTHT zJBnLwGM%!u&vlE%1ytJ=!xt~y_YkFLQb6bS!E+s8l7PiPGSt9xrmg?LV&&SL?J~cI zS(e9TF1?SGyh+M_p@o1dyWu7o7_6p;N6hO!;4~ z2B`I;y`;$ZdtBpvK5%oQ^p4eR2L)BH>B$FQeC*t)c`L71gXHPUa|vyu`Bnz)H$ZcXGve(}XvR!+*8a>BLV;+ryG1kt0=)ytl zNJxFUN{V7P?#|Cp85QTa@(*Q3%K-R(Pkv1N8YU*(d(Y}9?PQ(j;NzWoEVWRD-~H$=f>j9~PN^BM2okI(gY-&_&BCV6RP&I$FnSEM3d=0fCxbxA6~l>54-upTrw zYgX@%m>jsSGi`0cQt6b8cX~+02IghVlNblR7eI;0ps}mpWUcxty1yG56C5rh%ep(X z?)#2d?C<4t-KLc*EAn>>M8%HvC1TyBSoPNg(4id~H8JwO#I)Bf;N*y6ai6K9_bA`4 z_g9(-R;qyH&6I$`b42v|0V3Z8IXN*p*8g$gE98+JpXNY+jXxU0zsR^W$#V=KP z3AEFp@OL}WqwOfsV<)A^UTF4&HF1vQecz?LWE@p^Z2){=KEC_3Iopx_eS42>DeiDG zWMXGbYfG~W7C8s@@m<_?#Gqk;!&)_Key@^0xJxrJahv{B&{^!>TV7TEDZlP|$=ZCz zmX=ZWtt4QZKx**)lQQoW8y-XLiOQy#T`2t}p6l*S`68ojyH@UXJ-b~@tN`WpjF z%7%Yzv807gsO!v=!(2uR)16!&U5~VPrPHtGzUU?2w(b1Xchq}(5Ed^G|SD7IG+kvgyVksU) z(0R)SW1V(>&q2nM%Z!C9=;pTg!(8pPSc%H01urXmQI6Gi^dkYCYfu6b4^tW))b^U+ z$2K&iOgN_OU7n#GC2jgiXU{caO5hZt0(>k+c^(r><#m|#J^s?zA6pi;^#*rp&;aqL zRcZi0Q4HhVX3$ybclxo4FFJW*`IV`)Bj_L3rQe?5{wLJh168Ve1jZv+f1D}f0S$N= zm4i|9cEWz&C9~ZI3q*gwWH^<6sBWuphgy@S3Qy?MJiL>gwd|E<2h9-$3;gT9V~S6r z)cAcmE0KXOwDA5eJ02-75d~f?3;n7a9d_xPBJaO;Z)#@s7gk5$Qn(Fc^w@9c5W0zY z59is0?Mt^@Rolcn{4%)Ioat(kxQH6}hIykSA)zht=9F_W*D#<}N(k&&;k;&gKkWIL z0Of*sP=X(Uyu$Pw;?F@?j{}=>{aSHFcii#78FC^6JGrg-)!)MV4AKz>pXnhVgTgx8 z1&5Y=>|8RGA6++FrSy=__k_imx|z-EI@foKi>tK0Hq2LetjUotCgk2QFXaej!BWYL zJc{fv(&qA7UUJ|AXLc5z*_NW#yWzKtl(c8mEW{A>5Hj^gfZ^HC9lQNQ?RowXjmuCj4!!54Us1=hY z0{@-phvC}yls!PmA~_z>Y&n&IW9FQcj}9(OLO-t^NN$c0o}YksCUWt|DV(MJB%%Sr zdf}8!9ylU2TW!=T{?)g-ojAMKc>3pW;KiZ7f0;&g)k}K^#HBhE5ot)%oxq$*$W@b# zg4p<Ou`ME|Kd1WHK@8 zzLD+0(NHWa`B{em3Ye?@aVsEi>y#0XVZfaFuq#;X5C3{*ikRx7UY4FF{ZtNHNO?A_ z#Q?hwRv~D8fPEc%B5E-ZMI&TAmikl||EERumQCRh7p;)>fdZMxvKq;ky0}7IjhJph zW*uuu*(Y6)S;Od--8uR^R#sb$cmFCnPcj9PPCWhPN;n`i1Q#Qn>ii z{WR|0>8F`vf&#E(c2NsoH=I7Cd-FV|%(7a`i}gZw4N~QFFG2WtS^H%@c?%9UZ+kez z;PwGgg_r6V>Kn5n(nZ40P4qMyrCP3bDkJp@hp6&X3>gzC>=f@Hsen<%I~7W+x@}b> z0}Et*vx_50-q@PIV=(3&Tbm}}QRo*FP2@)A#XX-8jYspIhah`9ukPBr)$8>Tmtg&R z?JBoH17?+1@Y@r>anoKPQ}F8o9?vhcG79Cjv^V6ct709VOQwg{c0Q#rBSsSmK3Q;O zBpNihl3S0_IGVE)^`#94#j~$;7+u870yWiV$@={|GrBmuz4b)*bCOPkaN0{6$MvazOEBxFdKZDlbVvv{8_*kJ zfE6C`4&Kkz<5u%dEdStd85-5UHG5IOWbo8i9azgg#zw-(P1AA049hddAB*UdG3Vn0 zX`OgM+EM|<+KhJ<=k?z~WA5waVj?T9eBdfJGebVifBKS1u<$#vl^BvSg)xsnT5Aw_ZY#}v*LXO#htB>f}x3qDdDHoFeb zAq7;0CW;XJ`d&G*9V)@H&739DpfWYzdQt+Kx_E1K#Cg1EMtFa8eQRk_JuUdHD*2;W zR~XFnl!L2A?48O;_iqCVr1oxEXvOIiN_9CUVTZs3C~P+11}ebyTRLACiJuMIG#`xP zKlC|E(S@QvN+%pBc6vPiQS8KgQAUh75C0a2xcPQDD$}*bM&z~g8+=9ltmkT$;c;s z5_=8%i0H^fEAOQbHXf0;?DN5z-5+1 zDxj50yYkz4ox9p$HbZ|H?8ukAbLE^P$@h}L%i6QVcY>)i!w=hkv2zvrduut%!8>6b zcus3bh1w~L804EZ*s96?GB&F7c5?m?|t$-tp2rKMy>F*=4;w*jW}^;8v`st&8)c; z2Ct2{)?S(Z;@_mjAEjb8x=qAQvx=}S6l9?~H?PmP`-xu;ME*B8sm|!h@BX4>u(xg_ zIHmQzp4Tgf*J}Y=8STR5_s)GKcmgV!$JKTg@LO402{{Wrg>#D4-L%vjmtJ4r?p&$F!o-BOf7ej~ z6)BuK^^g1b#(E>$s`t3i13{6-mmSp7{;QkeG5v}GAN&lM2lQT$@(aQCcFP(%UyZbF z#$HLTqGT^@F#A29b0HqiJsRJAlh8kngU`BDI6 zJUE~&!cQ*&f95Ot$#mxU5+*^$qg_DWNdfu+1irglB7yDglzH()2!@#rpu)^3S8weW z_FE$=j^GTY*|5SH95O8o8W9FluYwB=2PwtbW|JG6kcV^dMVmX(wG+Otj;E$%gfu^K z!t~<3??8=()WQSycsBKy24>NjRtuZ>zxJIED;YXaUz$@0z4rl+TW zWxmvM$%4jYIpO>j5k1t1&}1VKM~s!eLsCVQ`TTjn3JRXZD~>GM z$-IT~(Y)flNqDkC%DfbxaV9?QuWCV&-U1yzrV@0jRhE;)ZO0=r-{s@W?HOFbRHDDV zq;eLo+wOW;nI|#mNf(J?RImB9{YSO2Y`9825Lz#u4(nk3)RGv3X8B(A$TsontJ8L! z9JP^eWxtKC?G8^xAZa1HECx*rp35s!^%;&@Jyk)NexVc)@U4$^X1Dag6`WKs|(HhZ#rzO2KEw3xh~-0<;|zcs0L>OcO#YYX{SN8m6`9pp+ zQG@q$I)T?aoe#AoR@%om_#z=c@ych!bj~lV13Qi-xg$i$hXEAB#l=t7QWENGbma4L zbBf*X*4oNYZUd_;1{Ln_ZeAwQv4z?n9$eoxJeI?lU9^!AB2Y~AwOSq67dT9ADZ)s@ zCRYS7W$Zpkdx$3T>7$I%3EI2ik~m!f7&$Djpt6kZqDWZJ-G{*_eXs*B8$1R4+I}Kf zqniwCI64r;>h2Lu{0c(#Atn)%E8&)=0S4BMhq9$`vu|Ct;^ur~gL`bD>J@l)P$q_A zO7b3HGOUG`vgH{}&&AgrFy%K^>? z>wf**coZ2vdSDcNYSm~dZ(vk6&m6bVKmVgrx-X<>{QzA!)2*L+HLTQz$e8UcB&Djq zl)-%s$ZtUN-R!4ZiG=L0#_P=BbUyH+YPmFl_ogkkQ$=s@T1v}rNnZ^eMaqJ|quc+6 z*ygceDOrldsL30w`H;rNu+IjlS+G~p&0SawXCA1+D zC%cZtjUkLNq%FadtHE?O(yQTP486A{1x<{krq#rpauNQaeyhM3*i0%tBpQHQo-u)x z{0{&KS`>}vf2_}b160XZO2$b)cyrHq7ZSeiSbRvaxnKUH{Q`-P(nL&^fcF2){vhN- zbX&WEjP7?b4A%0y6n_=m%l00uZ+}mCYO(!x?j$+O$*TqoD_Q5EoyDJ?w?^UIa491H zE}87(bR`X;@u#3Qy~9wWdWQIg1`cXrk$x9=ccR|RY1~%{fAJ@uq@J3e872x0v$hmv ze_KcL(wM|n0EOp;t{hKoohYyDmYO;!`7^Lx;0k=PWPGZpI>V5qYlzjSL_(%|mud50 z7#{p97s`U|Sn$WYF>-i{i4`kzlrV6a<}=72q2sAT7Zh{>P%*6B;Zl;~0xWymt10Mo zl5{bmR(wJefJpNGK=fSRP|mpCI-)Nf6?Pv==FcFmpSwF1%CTOucV{yqxSyx4Zws3O z8hr5Uyd%ezIO7?PnEO0T%af#KOiXD$e?V&OX-B|ZX-YsgSs%sv-6U+sLPuz{D4bq| zpd&|o5tNCmpT>(uIbRf?8c}d3IpOb3sn6>_dr*26R#ev<_~vi)wleW$PX|5)$_ z+_|=pi(0D(AB_sjQ;sQQSM&AWqzDO1@NHw;C9cPdXRKRI#@nUW)CgFxzQ1nyd!+h& zcjU!U=&u|>@}R(9D$%lu2TlV>@I2-n@fCr5PrZNVyKWR7hm zWjoy^p7v8m#$qN0K#8jT- zq`mSirDZDa1Jxm;Rg3rAPhC)LcI4@-RvKT+@9&KsR3b0_0zuM!Fg7u>oF>3bzOxZPU&$ab$Z9@ zY)f7pKh22I7ZykL{YsdjcqeN++=0a}elQM-4;Q)(`Ep3|VFHqnXOh14`!Bus& z9w%*EWK6AiAM{s$6~SEQS;A>ey$#`7)khZvamem{P?>k)5&7Sl&&NXKk}o!%vd;-! zpo2p-_h^b$DNBO>{h4JdGB=D>fvGIYN8v&XsfxU~VaefL?q} z3ekM?iOKkCzQHkBkhg=hD!@&(L}FcHKoa zbZ7)H1C|lHjwEb@tu=n^OvdHOo7o+W`0-y3KdP#bb~wM=Vr_gyoEq|#B?$&d$tals ziIs-&7isBpvS|CjC|7C&3I0SE?~`a%g~$PI%;au^cUp@ER3?mn-|vyu!$7MV6(uvt z+CcGuM(Ku2&G0tcRCo7#D$Dirfqef2qPOE5I)oCGzmR5G!o#Q~(k~)c=LpIfrhHQk zeAva6MilEifE7rgP1M7AyWmLOXK}i8?=z2;N=no)`IGm#y%aGE>-FN zyXCp0Sln{IsfOBuCdE*#@CQof%jzuU*jkR*Su3?5t}F(#g0BD0Zzu|1MDes8U7f9; z$JBg|mqTXt`muZ8=Z`3wx$uizZG_7>GI7tcfOHW`C2bKxNOR)XAwRkLOaHS4xwlH4 zDpU29#6wLXI;H?0Se`SRa&I_QmI{zo7p%uveBZ0KZKd9H6@U?YGArbfm)D*^5=&Rp z`k{35?Z5GbZnv>z@NmJ%+sx=1WanWg)8r}C_>EGR8mk(NR$pW<-l8OTU^_u3M@gwS z7}GGa1)`z5G|DZirw;FB@VhH7Dq*0qc=|9lLe{w2#`g+_nt>_%o<~9(VZe=zI*SSz4w43-_o>4E4`M@NPKTWZuQJs)?KXbWp1M zimd5F;?AP(LWcaI-^Sl{`~>tmxsQB9Y$Xi*{Zr#py_+I$vx7@NY`S?HFfS!hUiz$a z{>!&e1(16T!Om)m)&k1W#*d#GslD^4!TwiF2WjFBvi=Ms!ADT)ArEW6zfVuIXcXVk z>AHjPADW+mJzY`_Ieq(s?jbk4iD2Rb8*V3t6?I+E06(K8H!!xnDzO%GB;Z$N-{M|B zeT`jo%9)s%op*XZKDd6*)-^lWO{#RaIGFdBH+;XXjI(8RxpBc~azG1H^2v7c^bkFE zZCVPE+E*Q=FSe8Vm&6|^3ki{9~qafiMAf7i4APZg>b%&5>nT@pHH z%O*pOv(77?ZiT{W zBibx}Q12tRc7Py1NcZTp`Q4ey%T_nj@1WKg5Fz_Rjl4wlJQj)rtp8yL3r!Shy zvZvnmh!tH4T6Js-?vI0<-rzzl{mgT*S0d_7^AU_8gBg^03o-J=p(1o6kww2hx|!%T z-jqp}m^G*W?$!R#M%Ef?&2jYxmx+lXWZszpI4d$pUN`(S)|*c^CgdwY>Fa>> zgGBJhwe8y#Xd*q0=@SLEgPF>+Qe4?%E*v{a`||luZ~&dqMBrRfJ{SDMaJ!s_;cSJp zSqZHXIdc@@XteNySUZs^9SG7xK`8=NBNM)fRVOjw)D^)w%L2OPkTQ$Tel-J)GD3=YXy+F4in(ILy*A3m@3o73uv?JC}Q>f zrY&8SWmesiba0|3X-jmlMT3 z*ST|_U@O=i*sM_*48G)dgXqlwoFp5G6qSM3&%_f_*n!PiT>?cNI)fAUkA{qWnqdMi+aNK_yVQ&lx4UZknAc9FIzVk% zo6JmFH~c{_tK!gt4+o2>)zoP{sR}!!vfRjI=13!z5}ijMFQ4a4?QIg-BE4T6!#%?d&L;`j5=a`4is>U;%@Rd~ zXC~H7eGQhhYWhMPWf9znDbYIgwud(6$W3e>$W4$~d%qoJ z+JE`1g$qJ%>b|z*xCKenmpV$0pM=Gl-Y*LT8K+P)2X#;XYEFF4mRbc~jj?DM@(1e`nL=F4Syv)TKIePQUz)bZ?Bi3@G@HO$Aps1DvDGkYF50O$_welu^cL7;vPiMGho74$;4fDqKbE{U zd1h{;LfM#Fb|Z&uH~Rm_J)R~Vy4b;1?tW_A)Iz#S_=F|~pISaVkCnQ0&u%Yz%o#|! zS-TSg87LUfFSs{tTuM3$!06ZzH&MFtG)X-l7>3)V?Txuj2HyG*5u;EY2_5vU0ujA? zHXh5G%6e3y7v?AjhyX79pnRBVr}RmPmtrxoB7lkxEzChX^(vKd+sLh?SBic=Q)5nA zdz7Mw3_iA>;T^_Kl~?1|5t%GZ;ki_+i>Q~Q1EVdKZ)$Sh3LM@ea&D~{2HOG++7*wF zAC6jW4>fa~!Vp5+$Z{<)Qxb|{unMgCv2)@%3j=7)Zc%U<^i|SAF88s!A^+Xs!OASYT%7;Jx?olg_6NFP1475N z#0s<@E~FI}#LNQ{?B1;t+N$2k*`K$Hxb%#8tRQi*Z#No0J}Pl;HWb){l7{A8(pu#@ zfE-OTvEreoz1+p`9sUI%Y{e5L-oTP_^NkgpYhZjp&ykinnW;(fu1;ttpSsgYM8ABX4dHe_HxU+%M(D=~) zYM}XUJ5guZ;=_ZcOsC`_{CiU$zN3$+x&5C`vX-V3`8&RjlBs^rf00MNYZW+jCd~7N z%{jJuUUwY(M`8$`B>K&_48!Li682ZaRknMgQ3~dnlp8C?__!P2z@=Auv;T^$yrsNy zCARmaA@^Yo2sS%2$`031-+h9KMZsIHfB>s@}>Y(z988e!`%4=EDoAQ0kbk>+lCoK60Mx9P!~I zlq~wf7kcm_NFImt3ZYlE(b3O1K^QWiFb$V^a2Jlwvm(!XYx<`i@ZMS3UwFt{;x+-v zhx{m=m;4dgvkKp5{*lfSN3o^keSpp9{hlXj%=}e_7Ou{Yiw(J@NXuh*;pL6@$HsfB zh?v+r^cp@jQ4EspC#RqpwPY(}_SS$wZ{S959`C25777&sgtNh%XTCo9VHJC-G z;;wi9{-iv+ETiY;K9qvlEc04f;ZnUP>cUL_T*ms``EtGoP^B#Q>n2dSrbAg8a>*Lg zd0EJ^=tdW~7fbcLFsqryFEcy*-8!?;n%;F+8i{eZyCDaiYxghr z$8k>L|2&-!lhvuVdk!r-kpSFl`5F5d4DJr%M4-qOy3gdmQbqF1=aBtRM7)c_Ae?$b8 zQg4c8*KQ{XJmL)1c7#0Yn0#PTMEs4-IHPjkn0!=;JdhMXqzMLeh`yOylXROP- zl#z3+fwM9l3%VN(6R77ua*uI9%hO7l7{+Hcbr(peh;afUK?B4EC09J{-u{mv)+u#? zdKVBCPt`eU@IzL)OXA`Ebu`Xp?u0m%h&X41}FNfnJ*g1!1wcbbpo%F4x!-#R9ft!8{5`Ho}04?FI#Kg zL|k`tF1t_`ywdy8(wnTut>HND(qNnq%Sq=AvvZbXnLx|mJhi!*&lwG2g|edBdVgLy zjvVTKHAx(+&P;P#2Xobo7_RttUi)Nllc}}hX>|N?-u5g7VJ-NNdwYcaOG?NK=5)}` zMtOL;o|i0mSKm(UI_7BL_^6HnVOTkuPI6y@ZLR(H?c1cr-_ouSLp{5!bx^DiKd*Yb z{K78Ci&Twup zTKm)ioN|wcYy%Qnwb)IzbH>W!;Ah5Zdm_jRY`+VRJ2 zhkspZ9hbK3iQD91A$d!0*-1i#%x81|s+SPRmD}d~<1p6!A13(!vABP2kNgqEG z?AMgl^P+iRoIY(9@_I?n1829lGvAsRnHwS~|5vD2+Zi53j<5N4wNn0{q>>jF9*bI) zL$kMXM-awNOElF>{?Jr^tOz1glbwaD-M0OKOlTeW3C!1ZyxRbB>8JDof(O&R1bh%3x#>y2~<>OXO#IIedH0Q`(&&?eo-c~ z>*Ah#3~09unym~UC-UFqqI>{dmUD$Y4@evG#ORLI*{ZM)Jl=e1it!XzY($S3V zLG!Y6fCjE>x6r@5FG1n|8ompSZaJ>9)q6jqU;XxCQk9zV(?C9+i*>w z21+KYt1gXX&0`x3E)hS7I5}snbBzox9C@Xzcr|{B8Hw;SY1$}&BoYKXH^hpjW-RgJ z-Fb}tannKCv>y~^`r|(1Q9;+sZlYf3XPSX|^gR01UFtu$B*R;$sPZdIZShRr>|b@J z;#G{EdoY+O;REEjQ}X7_YzWLO+Ey3>a_KDe1CjSe| z6arqcEZ)CX!8r(si`dqbF$uu&pnf^Np{1f*TdJ`r2;@SaZ z#hb4xlaCA@Pwqj#LlUEe5L{I$k(Zj$d3(~)u(F%&xb8={N9hKxlZIO1ABsM{Mt|)2 zJ^t9Id;?%4PfR4&Ph9B9cFK~@tG3wlFW-0fXZS_L4U*EiAA%+`h%q2^6BCC;t0iO4V=s4Qug{M|iDV@s zC7|ef-dxiR7T&Mpre!%hiUhHM%3Qxi$Lzw6&(Tvlx9QA_7LhYq<(o~=Y>3ka-zrQa zhGpfFK@)#)rtfz61w35^sN1=IFw&Oc!Nah+8@qhJ0UEGr;JplaxOGI82OVqZHsqfX ze1}r{jy;G?&}Da}a7>SCDsFDuzuseeCKof|Dz2BPsP8? zY;a)Tkr2P~0^2BeO?wnzF_Ul-ekY=-w26VnU%U3f19Z-pj&2 z4J_a|o4Dci+MO)mPQIM>kdPG1xydiR9@#8m zh27D7GF{p|a{8({Q-Pr-;#jV{2zHR>lGoFtIfIpoMo?exuQyX_A;;l0AP4!)JEM$EwMInZkj+8*IHP4vKRd zKx_l-i*>A*C@{u%ct`y~s6MWAfO{@FPIX&sg8H{GMDc{4M3%$@c8&RAlw0-R<4DO3 trJqdc$mBpWeznn?E0M$F`|3v=`3%T2A17h;rxP7$%JLd=6(2u;`(N3pt&so# diff --git a/src/main/webapp/bower_components/bootstrap/js/.jshintrc b/src/main/webapp/bower_components/bootstrap/js/.jshintrc deleted file mode 100644 index e0722690b..000000000 --- a/src/main/webapp/bower_components/bootstrap/js/.jshintrc +++ /dev/null @@ -1,12 +0,0 @@ -{ - "validthis": true, - "laxcomma" : true, - "laxbreak" : true, - "browser" : true, - "eqnull" : true, - "debug" : true, - "devel" : true, - "boss" : true, - "expr" : true, - "asi" : true -} \ No newline at end of file diff --git a/src/main/webapp/bower_components/bootstrap/js/bootstrap-affix.js b/src/main/webapp/bower_components/bootstrap/js/bootstrap-affix.js deleted file mode 100644 index 7595fdb06..000000000 --- a/src/main/webapp/bower_components/bootstrap/js/bootstrap-affix.js +++ /dev/null @@ -1,117 +0,0 @@ -/* ========================================================== - * bootstrap-affix.js v2.3.0 - * http://twitter.github.com/bootstrap/javascript.html#affix - * ========================================================== - * Copyright 2012 Twitter, 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. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* AFFIX CLASS DEFINITION - * ====================== */ - - var Affix = function (element, options) { - this.options = $.extend({}, $.fn.affix.defaults, options) - this.$window = $(window) - .on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) - .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this)) - this.$element = $(element) - this.checkPosition() - } - - Affix.prototype.checkPosition = function () { - if (!this.$element.is(':visible')) return - - var scrollHeight = $(document).height() - , scrollTop = this.$window.scrollTop() - , position = this.$element.offset() - , offset = this.options.offset - , offsetBottom = offset.bottom - , offsetTop = offset.top - , reset = 'affix affix-top affix-bottom' - , affix - - if (typeof offset != 'object') offsetBottom = offsetTop = offset - if (typeof offsetTop == 'function') offsetTop = offset.top() - if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() - - 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 - - this.affixed = affix - this.unpin = affix == 'bottom' ? position.top - scrollTop : null - - this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) - } - - - /* AFFIX PLUGIN DEFINITION - * ======================= */ - - var old = $.fn.affix - - $.fn.affix = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('affix') - , options = typeof option == 'object' && option - if (!data) $this.data('affix', (data = new Affix(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.affix.Constructor = Affix - - $.fn.affix.defaults = { - offset: 0 - } - - - /* 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) - , data = $spy.data() - - data.offset = data.offset || {} - - data.offsetBottom && (data.offset.bottom = data.offsetBottom) - data.offsetTop && (data.offset.top = data.offsetTop) - - $spy.affix(data) - }) - }) - - -}(window.jQuery); \ No newline at end of file diff --git a/src/main/webapp/bower_components/bootstrap/js/bootstrap-alert.js b/src/main/webapp/bower_components/bootstrap/js/bootstrap-alert.js deleted file mode 100644 index b5627984e..000000000 --- a/src/main/webapp/bower_components/bootstrap/js/bootstrap-alert.js +++ /dev/null @@ -1,99 +0,0 @@ -/* ========================================================== - * bootstrap-alert.js v2.3.0 - * http://twitter.github.com/bootstrap/javascript.html#alerts - * ========================================================== - * Copyright 2012 Twitter, 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. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* ALERT CLASS DEFINITION - * ====================== */ - - var dismiss = '[data-dismiss="alert"]' - , Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.prototype.close = function (e) { - var $this = $(this) - , selector = $this.attr('data-target') - , $parent - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - $parent = $(selector) - - e && e.preventDefault() - - $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) - - $parent.trigger(e = $.Event('close')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - $parent - .trigger('closed') - .remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent.on($.support.transition.end, removeElement) : - removeElement() - } - - - /* ALERT PLUGIN DEFINITION - * ======================= */ - - var old = $.fn.alert - - $.fn.alert = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('alert') - if (!data) $this.data('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.alert.data-api', dismiss, Alert.prototype.close) - -}(window.jQuery); \ No newline at end of file diff --git a/src/main/webapp/bower_components/bootstrap/js/bootstrap-button.js b/src/main/webapp/bower_components/bootstrap/js/bootstrap-button.js deleted file mode 100644 index 045927b6b..000000000 --- a/src/main/webapp/bower_components/bootstrap/js/bootstrap-button.js +++ /dev/null @@ -1,105 +0,0 @@ -/* ============================================================ - * bootstrap-button.js v2.3.0 - * http://twitter.github.com/bootstrap/javascript.html#buttons - * ============================================================ - * Copyright 2012 Twitter, 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. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* BUTTON PUBLIC CLASS DEFINITION - * ============================== */ - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.button.defaults, options) - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - , $el = this.$element - , data = $el.data() - , val = $el.is('input') ? 'val' : 'html' - - state = state + 'Text' - data.resetText || $el.data('resetText', $el[val]()) - - $el[val](data[state] || this.options[state]) - - // push to event loop to allow forms to submit - setTimeout(function () { - state == 'loadingText' ? - $el.addClass(d).attr(d, d) : - $el.removeClass(d).removeAttr(d) - }, 0) - } - - Button.prototype.toggle = function () { - var $parent = this.$element.closest('[data-toggle="buttons-radio"]') - - $parent && $parent - .find('.active') - .removeClass('active') - - this.$element.toggleClass('active') - } - - - /* BUTTON PLUGIN DEFINITION - * ======================== */ - - var old = $.fn.button - - $.fn.button = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('button') - , options = typeof option == 'object' && option - if (!data) $this.data('button', (data = new Button(this, options))) - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - $.fn.button.defaults = { - loadingText: 'loading...' - } - - $.fn.button.Constructor = Button - - - /* BUTTON NO CONFLICT - * ================== */ - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - /* BUTTON DATA-API - * =============== */ - - $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - $btn.button('toggle') - }) - -}(window.jQuery); \ No newline at end of file diff --git a/src/main/webapp/bower_components/bootstrap/js/bootstrap-carousel.js b/src/main/webapp/bower_components/bootstrap/js/bootstrap-carousel.js deleted file mode 100644 index 604552012..000000000 --- a/src/main/webapp/bower_components/bootstrap/js/bootstrap-carousel.js +++ /dev/null @@ -1,207 +0,0 @@ -/* ========================================================== - * bootstrap-carousel.js v2.3.0 - * http://twitter.github.com/bootstrap/javascript.html#carousel - * ========================================================== - * Copyright 2012 Twitter, 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. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* CAROUSEL CLASS DEFINITION - * ========================= */ - - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.options.pause == 'hover' && this.$element - .on('mouseenter', $.proxy(this.pause, this)) - .on('mouseleave', $.proxy(this.cycle, this)) - } - - Carousel.prototype = { - - cycle: function (e) { - if (!e) this.paused = false - if (this.interval) clearInterval(this.interval); - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - return this - } - - , getActiveIndex: function () { - this.$active = this.$element.find('.item.active') - this.$items = this.$active.parent().children() - return this.$items.index(this.$active) - } - - , to: function (pos) { - var activeIndex = this.getActiveIndex() - , that = this - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) { - return this.$element.one('slid', function () { - that.to(pos) - }) - } - - if (activeIndex == pos) { - return this.pause().cycle() - } - - return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) - } - - , pause: function (e) { - if (!e) this.paused = true - if (this.$element.find('.next, .prev').length && $.support.transition.end) { - this.$element.trigger($.support.transition.end) - this.cycle() - } - clearInterval(this.interval) - this.interval = null - return this - } - - , next: function () { - if (this.sliding) return - return this.slide('next') - } - - , prev: function () { - if (this.sliding) return - return this.slide('prev') - } - - , slide: function (type, next) { - var $active = this.$element.find('.item.active') - , $next = next || $active[type]() - , isCycling = this.interval - , direction = type == 'next' ? 'left' : 'right' - , fallback = type == 'next' ? 'first' : 'last' - , that = this - , e - - this.sliding = true - - isCycling && this.pause() - - $next = $next.length ? $next : this.$element.find('.item')[fallback]() - - e = $.Event('slide', { - relatedTarget: $next[0] - , direction: direction - }) - - if ($next.hasClass('active')) return - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - this.$element.one('slid', function () { - var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) - $nextIndicator && $nextIndicator.addClass('active') - }) - } - - if ($.support.transition && this.$element.hasClass('slide')) { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - this.$element.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') }, 0) - }) - } else { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger('slid') - } - - isCycling && this.cycle() - - return this - } - - } - - - /* CAROUSEL PLUGIN DEFINITION - * ========================== */ - - var old = $.fn.carousel - - $.fn.carousel = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('carousel') - , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) - , action = typeof option == 'string' ? option : options.slide - if (!data) $this.data('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.defaults = { - interval: 5000 - , pause: 'hover' - } - - $.fn.carousel.Constructor = Carousel - - - /* CAROUSEL NO CONFLICT - * ==================== */ - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - /* CAROUSEL DATA-API - * ================= */ - - $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { - var $this = $(this), href - , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 - , options = $.extend({}, $target.data(), $this.data()) - , slideIndex - - $target.carousel(options) - - if (slideIndex = $this.attr('data-slide-to')) { - $target.data('carousel').pause().to(slideIndex).cycle() - } - - e.preventDefault() - }) - -}(window.jQuery); \ No newline at end of file diff --git a/src/main/webapp/bower_components/bootstrap/js/bootstrap-collapse.js b/src/main/webapp/bower_components/bootstrap/js/bootstrap-collapse.js deleted file mode 100644 index 7bbad8e43..000000000 --- a/src/main/webapp/bower_components/bootstrap/js/bootstrap-collapse.js +++ /dev/null @@ -1,167 +0,0 @@ -/* ============================================================= - * bootstrap-collapse.js v2.3.0 - * http://twitter.github.com/bootstrap/javascript.html#collapse - * ============================================================= - * Copyright 2012 Twitter, 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. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* COLLAPSE PUBLIC CLASS DEFINITION - * ================================ */ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.collapse.defaults, options) - - if (this.options.parent) { - this.$parent = $(this.options.parent) - } - - this.options.toggle && this.toggle() - } - - Collapse.prototype = { - - constructor: Collapse - - , dimension: function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - , show: function () { - var dimension - , scroll - , actives - , hasData - - if (this.transitioning || this.$element.hasClass('in')) return - - dimension = this.dimension() - scroll = $.camelCase(['scroll', dimension].join('-')) - actives = this.$parent && this.$parent.find('> .accordion-group > .in') - - if (actives && actives.length) { - hasData = actives.data('collapse') - if (hasData && hasData.transitioning) return - actives.collapse('hide') - hasData || actives.data('collapse', null) - } - - this.$element[dimension](0) - this.transition('addClass', $.Event('show'), 'shown') - $.support.transition && this.$element[dimension](this.$element[0][scroll]) - } - - , hide: function () { - var dimension - if (this.transitioning || !this.$element.hasClass('in')) return - dimension = this.dimension() - this.reset(this.$element[dimension]()) - this.transition('removeClass', $.Event('hide'), 'hidden') - this.$element[dimension](0) - } - - , reset: function (size) { - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - [dimension](size || 'auto') - [0].offsetWidth - - this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') - - return this - } - - , transition: function (method, startEvent, completeEvent) { - var that = this - , complete = function () { - if (startEvent.type == 'show') that.reset() - that.transitioning = 0 - that.$element.trigger(completeEvent) - } - - this.$element.trigger(startEvent) - - if (startEvent.isDefaultPrevented()) return - - this.transitioning = 1 - - this.$element[method]('in') - - $.support.transition && this.$element.hasClass('collapse') ? - this.$element.one($.support.transition.end, complete) : - complete() - } - - , 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) - , data = $this.data('collapse') - , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) - if (!data) $this.data('collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.collapse.defaults = { - toggle: true - } - - $.fn.collapse.Constructor = Collapse - - - /* COLLAPSE NO CONFLICT - * ==================== */ - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - /* COLLAPSE DATA-API - * ================= */ - - $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { - var $this = $(this), href - , target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - , option = $(target).data('collapse') ? 'toggle' : $this.data() - $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') - $(target).collapse(option) - }) - -}(window.jQuery); \ No newline at end of file diff --git a/src/main/webapp/bower_components/bootstrap/js/bootstrap-dropdown.js b/src/main/webapp/bower_components/bootstrap/js/bootstrap-dropdown.js deleted file mode 100644 index ec86cf0d7..000000000 --- a/src/main/webapp/bower_components/bootstrap/js/bootstrap-dropdown.js +++ /dev/null @@ -1,165 +0,0 @@ -/* ============================================================ - * bootstrap-dropdown.js v2.3.0 - * http://twitter.github.com/bootstrap/javascript.html#dropdowns - * ============================================================ - * Copyright 2012 Twitter, 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. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* DROPDOWN CLASS DEFINITION - * ========================= */ - - var toggle = '[data-toggle=dropdown]' - , Dropdown = function (element) { - var $el = $(element).on('click.dropdown.data-api', this.toggle) - $('html').on('click.dropdown.data-api', function () { - $el.parent().removeClass('open') - }) - } - - Dropdown.prototype = { - - constructor: Dropdown - - , toggle: function (e) { - var $this = $(this) - , $parent - , isActive - - if ($this.is('.disabled, :disabled')) return - - $parent = getParent($this) - - isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - $parent.toggleClass('open') - } - - $this.focus() - - return false - } - - , keydown: function (e) { - var $this - , $items - , $active - , $parent - , isActive - , index - - if (!/(38|40|27)/.test(e.keyCode)) return - - $this = $(this) - - e.preventDefault() - e.stopPropagation() - - if ($this.is('.disabled, :disabled')) return - - $parent = getParent($this) - - isActive = $parent.hasClass('open') - - if (!isActive || (isActive && e.keyCode == 27)) { - if (e.which == 27) $parent.find(toggle).focus() - return $this.click() - } - - $items = $('[role=menu] li:not(.divider):visible a', $parent) - - if (!$items.length) return - - 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() { - $(toggle).each(function () { - getParent($(this)).removeClass('open') - }) - } - - function getParent($this) { - var selector = $this.attr('data-target') - , $parent - - if (!selector) { - selector = $this.attr('href') - selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - $parent = selector && $(selector) - - if (!$parent || !$parent.length) $parent = $this.parent() - - return $parent - } - - - /* DROPDOWN PLUGIN DEFINITION - * ========================== */ - - var old = $.fn.dropdown - - $.fn.dropdown = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('dropdown') - if (!data) $this.data('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.dropdown.data-api', clearMenus) - .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) - .on('.dropdown-menu', function (e) { e.stopPropagation() }) - .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle) - .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) - -}(window.jQuery); diff --git a/src/main/webapp/bower_components/bootstrap/js/bootstrap-modal.js b/src/main/webapp/bower_components/bootstrap/js/bootstrap-modal.js deleted file mode 100644 index b5ffa95b3..000000000 --- a/src/main/webapp/bower_components/bootstrap/js/bootstrap-modal.js +++ /dev/null @@ -1,247 +0,0 @@ -/* ========================================================= - * bootstrap-modal.js v2.3.0 - * http://twitter.github.com/bootstrap/javascript.html#modals - * ========================================================= - * Copyright 2012 Twitter, 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. - * ========================================================= */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* MODAL CLASS DEFINITION - * ====================== */ - - var Modal = function (element, options) { - this.options = options - this.$element = $(element) - .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) - this.options.remote && this.$element.find('.modal-body').load(this.options.remote) - } - - Modal.prototype = { - - constructor: Modal - - , toggle: function () { - return this[!this.isShown ? 'show' : 'hide']() - } - - , show: function () { - var that = this - , e = $.Event('show') - - this.$element.trigger(e) - - if (this.isShown || e.isDefaultPrevented()) return - - this.isShown = true - - this.escape() - - 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() - - if (transition) { - that.$element[0].offsetWidth // force reflow - } - - that.$element - .addClass('in') - .attr('aria-hidden', false) - - that.enforceFocus() - - transition ? - that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) : - that.$element.focus().trigger('shown') - - }) - } - - , hide: function (e) { - e && e.preventDefault() - - var that = this - - e = $.Event('hide') - - this.$element.trigger(e) - - if (!this.isShown || e.isDefaultPrevented()) return - - this.isShown = false - - this.escape() - - $(document).off('focusin.modal') - - this.$element - .removeClass('in') - .attr('aria-hidden', true) - - $.support.transition && this.$element.hasClass('fade') ? - this.hideWithTransition() : - this.hideModal() - } - - , enforceFocus: function () { - var that = this - $(document).on('focusin.modal', function (e) { - if (that.$element[0] !== e.target && !that.$element.has(e.target).length) { - that.$element.focus() - } - }) - } - - , escape: function () { - var that = this - if (this.isShown && this.options.keyboard) { - this.$element.on('keyup.dismiss.modal', function ( e ) { - e.which == 27 && that.hide() - }) - } else if (!this.isShown) { - this.$element.off('keyup.dismiss.modal') - } - } - - , hideWithTransition: function () { - var that = this - , timeout = setTimeout(function () { - that.$element.off($.support.transition.end) - that.hideModal() - }, 500) - - this.$element.one($.support.transition.end, function () { - clearTimeout(timeout) - that.hideModal() - }) - } - - , hideModal: function () { - var that = this - this.$element.hide() - this.backdrop(function () { - that.removeBackdrop() - that.$element.trigger('hidden') - }) - } - - , removeBackdrop: function () { - this.$backdrop.remove() - this.$backdrop = null - } - - , backdrop: function (callback) { - var that = this - , animate = this.$element.hasClass('fade') ? 'fade' : '' - - if (this.isShown && this.options.backdrop) { - var doAnimate = $.support.transition && animate - - this.$backdrop = $('