diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0c15b5d..0000000 --- a/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -*.iml -.idea -target -build -.DS_Store -.gradle -local.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a3616f3..0000000 --- a/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -language: android - -before_script: - - "export JAVA_OPTS=-Xmx512m" - -android: - components: - - tools - - platform-tools - - tools # This duplication is intented to make travis accept license, please check https://github.com/travis-ci/docs-travis-ci-com/issues/779 - - build-tools-25.0.1 - - android-25 - - extra-android-m2repository - licenses: - - 'android-sdk-preview-license-52d11cd2' - - 'android-sdk-license-.+' - - 'google-gdk-license-.+' - -jdk: - - oraclejdk8 - -branches: - except: - - gh-pages - -notifications: - email: false - -sudo: false - -cache: - directories: - - $HOME/.m2 diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 08ca900..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -# 1.0.0 / 2016-03-22 - -Initial public release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 63d0028..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,12 +0,0 @@ -Contributing -============ - -If you would like to contribute code to LightCycle you can do so through GitHub by -forking the repository and sending a pull request. - -When submitting code, please make every effort to follow existing conventions -and style in order to keep the code as readable as possible. - -All pull requests will be validated by Travis-ci in any case and must pass before being merged. - -Checkstyle failures during compilation indicate errors in your style and will be displayed in the console output of the build (including in Travis-CI output), or can be viewed in the checkstyle-result.xml file. diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d9a10c0..0000000 --- a/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/README.md b/README.md deleted file mode 100644 index f6c5e5e..0000000 --- a/README.md +++ /dev/null @@ -1,184 +0,0 @@ -# LightCycle - -[![Hex.pm](https://img.shields.io/hexpm/l/plug.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![Platform](https://img.shields.io/badge/platform-android-green.svg)](http://developer.android.com/index.html) - -LightCycle is an Android library that helps break logic out of `Activity` and `Fragment` classes into small, self-contained components called LightCycles. - -Fields that are annotated `@LightCycle` and implement the LightCycle API within a `LightCycleActivity` or `LightCycleFragment` will be bound to that `Activity` or `Fragment` lifecycle. - -## Usage - -```java -public class MyActivity extends LightCycleAppCompatActivity { - @LightCycle MyController controller = new MyController(); - - @Override - protected void setActivityContentView() { - setContentView(R.layout.main); - } -} -``` - -```java -public class MyController extends DefaultActivityLightCycle { - - @Override - public void onPause(MyActivity activity) { - // MyActivity was paused - } - - [...] - - @Override - public void onResume(MyActivity activity) { - // MyActivity was resumed - } -} -``` - -## Philosophy - -LightCycle lets self-contained classes respond to Android’s lifecycle events. This supports composition over inheritance and promotes components that follow the single responsibility principle. We believe it helps us write more readable, maintainable and testable code. It works particularly well alongside dependency injection. - -- `Activity` & `Fragment` classes: - - Inflate layouts and configure Android specifics - - Declare LightCycles -- A LightCycle component is responsible for an isolated chunk of logic (such as presentation, tracking etc.) - -A LightCycle doesn't know about other LightCycles. There is no guarantee for ordering when multiple LightCycles receive the same lifecycle callback. - -## Examples - -- [basic](https://github.com/soundcloud/lightcycle/tree/master/examples/basic) -- ["real world"](https://github.com/soundcloud/lightcycle/tree/master/examples/real-world) - -## Documentation - -### LightCycle - -There are 3 types of LightCycles - the API is comparable to the [`ActivityLifecycleCallbacks`](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html) from the Android SDK: -- `ActivityLightCycle` -- `FragmentLightCycle` -- `SupportFragmentLightCycle` - -For convenience, default implementations are provided: -- `DefaultActivityLightCycle` -- `DefaultFragmentLightCycle` -- `DefaultSupportFragmentLightCycle` - -### Dispatcher - -This dispatches an `Activity` or `Fragment` lifecycle callback to attached LightCycles. The API defines a single `bind` method. See the `LightCycleDispatcher` interface. - -#### Built-in dispatchers - -Three types of dispatchers are provided: -- `ActivityLightCycleDispatcher` -- `FragmentLightCycleDispatcher` -- `SupportFragmentLightCycleDispatcher` - -Note: these built-in classes are both dispatchers and LightCycles, meaning that you can nest LightCycles. - -```java -public class MyActivity extends LightCycleAppCompatActivity { - @LightCycle MyController controller = new MyController(); - - @Override - protected void setActivityContentView() { - setContentView(R.layout.main); - } -} -``` - -```java -public class MyController extends ActivityLightCycleDispatcher { - @LightCycle MySubController1 controller = new MyController1(); - @LightCycle MySubController2 controller = new MyController2(); - - @Override - public void onCreate(Bundle savedInstanceState) { - [...] // <- specific init - super.onCreate(savedInstanceState) // <- call super to dispatch. - } -} -``` - -#### Provided base class dispatchers - -The following base activities are provided so far: -- `LightCycleActionBarActivity` -- `LightCycleAppCompatActivity` -- `LightCycleFragment` -- `LightCycleSupportFragment` - -#### Adding LightCycle to your own base `Activity` or `Fragment` - -/!\ Please, read carefully the following steps (item 2 in particular). - -To add LightCycles to your `MyBaseActivity`, your `Activity` must: -- Implement the `LightCycleDispatcher` interface. _Note: The processor needs to know the exact type being dispatched, so if your base activity is templated then the activities inheriting from it must explicitly `implements LightCycleDispatcher>`_ (for more details, refer to https://github.com/soundcloud/lightcycle/issues/49) -- Dispatch all the lifecycle methods -- Bind fields annotated `@LightCycle` with `LightCycles.bind(this)` - -The same technique applies for `Fragment`. - -```java -public class MyBaseActivity extends Activity implements LightCycleDispatcher> { - - private final ActivityLightCycleDispatcher lightCycleDispatcher; - - @Override - public void bind(ActivityLightCycle lightCycle) { - lightCycleDispatcher.bind(lightCycle); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - LightCycles.bind(this); - lightCycleDispatcher.onCreate((MyBaseActivity) this, savedInstanceState); - } - - [...] - - @Override - protected void onDestroy() { - lightCycleDispatcher.onDestroy((MyBaseActivity) this); - super.onDestroy(); - } -} -``` - -See for example [LightCycleActionBarActivity](lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleActionBarActivity.java) or [LightCycleSupportFragment](lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleSupportFragment.java). - -## Build integration - -Gradle: - -```gradle -ext.lightCycleVersion= - -dependencies { - compile "com.soundcloud.lightcycle:lightcycle-lib:$lightCycleVersion" - annotationProcessor "com.soundcloud.lightcycle:lightcycle-processor:$lightCycleVersion" -} -``` - -Or if you're using a version of the Android gradle plugin below `2.2.0` - -```gradle -buildscript { - dependencies { - classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' - } -} - -apply plugin: 'com.neenbedankt.android-apt' - -ext.lightCycleVersion= - -dependencies { - compile "com.soundcloud.lightcycle:lightcycle-lib:$lightCycleVersion" - apt "com.soundcloud.lightcycle:lightcycle-processor:$lightCycleVersion" -} -``` diff --git a/assets/images/icon-github.png b/assets/images/icon-github.png new file mode 100755 index 0000000..a9c6940 Binary files /dev/null and b/assets/images/icon-github.png differ diff --git a/assets/images/logo-soundcloud.png b/assets/images/logo-soundcloud.png new file mode 100644 index 0000000..b4aeb1d Binary files /dev/null and b/assets/images/logo-soundcloud.png differ diff --git a/assets/javascripts/bootstrap.min.js b/assets/javascripts/bootstrap.min.js new file mode 100755 index 0000000..95c5ac5 --- /dev/null +++ b/assets/javascripts/bootstrap.min.js @@ -0,0 +1,6 @@ +/*! +* Bootstrap.js by @fat & @mdo +* Copyright 2012 Twitter, Inc. +* http://www.apache.org/licenses/LICENSE-2.0.txt +*/ +!function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||s.toggleClass("open"),n.focus(),!1},keydown:function(n){var r,s,o,u,a,f;if(!/(38|40|27)/.test(n.keyCode))return;r=e(this),n.preventDefault(),n.stopPropagation();if(r.is(".disabled, :disabled"))return;u=i(r),a=u.hasClass("open");if(!a||a&&n.keyCode==27)return n.which==27&&u.find(t).focus(),r.click();s=e("[role=menu] li:not(.divider):visible a",u);if(!s.length)return;f=s.index(s.filter(":focus")),n.keyCode==38&&f>0&&f--,n.keyCode==40&&f').appendTo(document.body),this.$backdrop.click(this.options.backdrop=="static"?e.proxy(this.$element[0].focus,this.$element[0]):e.proxy(this.hide,this)),i&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in");if(!t)return;i?this.$backdrop.one(e.support.transition.end,t):t()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),e.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(e.support.transition.end,t):t()):t&&t()}};var n=e.fn.modal;e.fn.modal=function(n){return this.each(function(){var r=e(this),i=r.data("modal"),s=e.extend({},e.fn.modal.defaults,r.data(),typeof n=="object"&&n);i||r.data("modal",i=new t(this,s)),typeof n=="string"?i[n]():s.show&&i.show()})},e.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},e.fn.modal.Constructor=t,e.fn.modal.noConflict=function(){return e.fn.modal=n,this},e(document).on("click.modal.data-api",'[data-toggle="modal"]',function(t){var n=e(this),r=n.attr("href"),i=e(n.attr("data-target")||r&&r.replace(/.*(?=#[^\s]+$)/,"")),s=i.data("modal")?"toggle":e.extend({remote:!/#/.test(r)&&r},i.data(),n.data());t.preventDefault(),i.modal(s).one("hide",function(){n.focus()})})}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i,s,o,u,a;this.type=t,this.$element=e(n),this.options=this.getOptions(r),this.enabled=!0,o=this.options.trigger.split(" ");for(a=o.length;a--;)u=o[a],u=="click"?this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this)):u!="manual"&&(i=u=="hover"?"mouseenter":"focus",s=u=="hover"?"mouseleave":"blur",this.$element.on(i+"."+this.type,this.options.selector,e.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,e.proxy(this.leave,this)));this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,this.$element.data(),t),t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var n=e.fn[this.type].defaults,r={},i;this._options&&e.each(this._options,function(e,t){n[e]!=t&&(r[e]=t)},this),i=e(t.currentTarget)[this.type](r).data(this.type);if(!i.options.delay||!i.options.delay.show)return i.show();clearTimeout(this.timeout),i.hoverState="in",this.timeout=setTimeout(function(){i.hoverState=="in"&&i.show()},i.options.delay.show)},leave:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);this.timeout&&clearTimeout(this.timeout);if(!n.options.delay||!n.options.delay.hide)return n.hide();n.hoverState="out",this.timeout=setTimeout(function(){n.hoverState=="out"&&n.hide()},n.options.delay.hide)},show:function(){var t,n,r,i,s,o,u=e.Event("show");if(this.hasContent()&&this.enabled){this.$element.trigger(u);if(u.isDefaultPrevented())return;t=this.tip(),this.setContent(),this.options.animation&&t.addClass("fade"),s=typeof this.options.placement=="function"?this.options.placement.call(this,t[0],this.$element[0]):this.options.placement,t.detach().css({top:0,left:0,display:"block"}),this.options.container?t.appendTo(this.options.container):t.insertAfter(this.$element),n=this.getPosition(),r=t[0].offsetWidth,i=t[0].offsetHeight;switch(s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}this.applyPlacement(o,s),this.$element.trigger("shown")}},applyPlacement:function(e,t){var n=this.tip(),r=n[0].offsetWidth,i=n[0].offsetHeight,s,o,u,a;n.offset(e).addClass(t).addClass("in"),s=n[0].offsetWidth,o=n[0].offsetHeight,t=="top"&&o!=i&&(e.top=e.top+i-o,a=!0),t=="bottom"||t=="top"?(u=0,e.left<0&&(u=e.left*-2,e.left=0,n.offset(e),s=n[0].offsetWidth,o=n[0].offsetHeight),this.replaceArrow(u-r+s,s,"left")):this.replaceArrow(o-i,o,"top"),a&&n.offset(e)},replaceArrow:function(e,t,n){this.arrow().css(n,e?50*(1-e/t)+"%":"")},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.options.html?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function i(){var t=setTimeout(function(){n.off(e.support.transition.end).detach()},500);n.one(e.support.transition.end,function(){clearTimeout(t),n.detach()})}var t=this,n=this.tip(),r=e.Event("hide");this.$element.trigger(r);if(r.isDefaultPrevented())return;return n.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?i():n.detach(),this.$element.trigger("hidden"),this},fixTitle:function(){var e=this.$element;(e.attr("title")||typeof e.attr("data-original-title")!="string")&&e.attr("data-original-title",e.attr("title")||"").attr("title","")},hasContent:function(){return this.getTitle()},getPosition:function(){var t=this.$element[0];return e.extend({},typeof t.getBoundingClientRect=="function"?t.getBoundingClientRect():{width:t.offsetWidth,height:t.offsetHeight},this.$element.offset())},getTitle:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-original-title")||(typeof n.title=="function"?n.title.call(t[0]):n.title),e},tip:function(){return this.$tip=this.$tip||e(this.options.template)},arrow:function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(t){var n=t?e(t.currentTarget)[this.type](this._options).data(this.type):this;n.tip().hasClass("in")?n.hide():n.show()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var n=e.fn.tooltip;e.fn.tooltip=function(n){return this.each(function(){var r=e(this),i=r.data("tooltip"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},e.fn.tooltip.noConflict=function(){return e.fn.tooltip=n,this}}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),n=this.getContent();e.find(".popover-title")[this.options.html?"html":"text"](t),e.find(".popover-content")[this.options.html?"html":"text"](n),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,n=this.options;return e=(typeof n.content=="function"?n.content.call(t[0]):n.content)||t.attr("data-content"),e},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var n=e.fn.popover;e.fn.popover=function(n){return this.each(function(){var r=e(this),i=r.data("popover"),s=typeof n=="object"&&n;i||r.data("popover",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'

'}),e.fn.popover.noConflict=function(){return e.fn.popover=n,this}}(window.jQuery),!function(e){"use strict";function t(t,n){var r=e.proxy(this.process,this),i=e(t).is("body")?e(window):e(t),s;this.options=e.extend({},e.fn.scrollspy.defaults,n),this.$scrollElement=i.on("scroll.scroll-spy.data-api",r),this.selector=(this.options.target||(s=e(t).attr("href"))&&s.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=e("body"),this.refresh(),this.process()}t.prototype={constructor:t,refresh:function(){var t=this,n;this.offsets=e([]),this.targets=e([]),n=this.$body.find(this.selector).map(function(){var n=e(this),r=n.data("target")||n.attr("href"),i=/^#\w/.test(r)&&e(r);return i&&i.length&&[[i.position().top+(!e.isWindow(t.$scrollElement.get(0))&&t.$scrollElement.scrollTop()),r]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},process:function(){var e=this.$scrollElement.scrollTop()+this.options.offset,t=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,n=t-this.$scrollElement.height(),r=this.offsets,i=this.targets,s=this.activeTarget,o;if(e>=n)return s!=(o=i.last()[0])&&this.activate(o);for(o=r.length;o--;)s!=i[o]&&e>=r[o]&&(!r[o+1]||e<=r[o+1])&&this.activate(i[o])},activate:function(t){var n,r;this.activeTarget=t,e(this.selector).parent(".active").removeClass("active"),r=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',n=e(r).parent("li").addClass("active"),n.parent(".dropdown-menu").length&&(n=n.closest("li.dropdown").addClass("active")),n.trigger("activate")}};var n=e.fn.scrollspy;e.fn.scrollspy=function(n){return this.each(function(){var r=e(this),i=r.data("scrollspy"),s=typeof n=="object"&&n;i||r.data("scrollspy",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.scrollspy.Constructor=t,e.fn.scrollspy.defaults={offset:10},e.fn.scrollspy.noConflict=function(){return e.fn.scrollspy=n,this},e(window).on("load",function(){e('[data-spy="scroll"]').each(function(){var t=e(this);t.scrollspy(t.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t){this.element=e(t)};t.prototype={constructor:t,show:function(){var t=this.element,n=t.closest("ul:not(.dropdown-menu)"),r=t.attr("data-target"),i,s,o;r||(r=t.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,""));if(t.parent("li").hasClass("active"))return;i=n.find(".active:last a")[0],o=e.Event("show",{relatedTarget:i}),t.trigger(o);if(o.isDefaultPrevented())return;s=e(r),this.activate(t.parent("li"),n),this.activate(s,s.parent(),function(){t.trigger({type:"shown",relatedTarget:i})})},activate:function(t,n,r){function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),t.addClass("active"),s?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu")&&t.closest("li.dropdown").addClass("active"),r&&r()}var i=n.find("> .active"),s=r&&e.support.transition&&i.hasClass("fade");s?i.one(e.support.transition.end,o):o(),i.removeClass("in")}};var n=e.fn.tab;e.fn.tab=function(n){return this.each(function(){var r=e(this),i=r.data("tab");i||r.data("tab",i=new t(this)),typeof n=="string"&&i[n]()})},e.fn.tab.Constructor=t,e.fn.tab.noConflict=function(){return e.fn.tab=n,this},e(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(t){t.preventDefault(),e(this).tab("show")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=e(this.options.menu),this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:t.top+t.height,left:t.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length"+t+""})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),t.first().addClass("active"),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("focus",e.proxy(this.focus,this)).on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this)).on("mouseleave","li",e.proxy(this.mouseleave,this))},eventSupported:function(e){var t=e in this.$element;return t||(this.$element.setAttribute(e,"return;"),t=typeof this.$element[e]=="function"),t},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},focus:function(e){this.focused=!0},blur:function(e){this.focused=!1,!this.mousedover&&this.shown&&this.hide()},click:function(e){e.stopPropagation(),e.preventDefault(),this.select(),this.$element.focus()},mouseenter:function(t){this.mousedover=!0,this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")},mouseleave:function(e){this.mousedover=!1,!this.focused&&this.shown&&this.hide()}};var n=e.fn.typeahead;e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'',item:'
  • ',minLength:1},e.fn.typeahead.Constructor=t,e.fn.typeahead.noConflict=function(){return e.fn.typeahead=n,this},e(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;n.typeahead(n.data())})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=e.extend({},e.fn.affix.defaults,n),this.$window=e(window).on("scroll.affix.data-api",e.proxy(this.checkPosition,this)).on("click.affix.data-api",e.proxy(function(){setTimeout(e.proxy(this.checkPosition,this),1)},this)),this.$element=e(t),this.checkPosition()};t.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var t=e(document).height(),n=this.$window.scrollTop(),r=this.$element.offset(),i=this.options.offset,s=i.bottom,o=i.top,u="affix affix-top affix-bottom",a;typeof i!="object"&&(s=o=i),typeof o=="function"&&(o=i.top()),typeof s=="function"&&(s=i.bottom()),a=this.unpin!=null&&n+this.unpin<=r.top?!1:s!=null&&r.top+this.$element.height()>=t-s?"bottom":o!=null&&n<=o?"top":!1;if(this.affixed===a)return;this.affixed=a,this.unpin=a=="bottom"?r.top-n:null,this.$element.removeClass(u).addClass("affix"+(a?"-"+a:""))};var n=e.fn.affix;e.fn.affix=function(n){return this.each(function(){var r=e(this),i=r.data("affix"),s=typeof n=="object"&&n;i||r.data("affix",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.affix.Constructor=t,e.fn.affix.defaults={offset:0},e.fn.affix.noConflict=function(){return e.fn.affix=n,this},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var t=e(this),n=t.data();n.offset=n.offset||{},n.offsetBottom&&(n.offset.bottom=n.offsetBottom),n.offsetTop&&(n.offset.top=n.offsetTop),t.affix(n)})})}(window.jQuery); \ No newline at end of file diff --git a/assets/javascripts/highlight.pack.js b/assets/javascripts/highlight.pack.js new file mode 100644 index 0000000..cc304df --- /dev/null +++ b/assets/javascripts/highlight.pack.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.9.0 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return I[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function i(e){return k.test(e)}function a(e){var n,t,r,a,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return R(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(a=o[n],i(a)||R(a))return a}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,i){for(var a=e.firstChild;a;a=a.nextSibling)3===a.nodeType?i+=a.nodeValue.length:1===a.nodeType&&(n.push({event:"start",offset:i,node:a}),i=r(a,i),t(a).match(/br|hr|img|input/)||n.push({event:"stop",offset:i,node:a}));return i}(e,0),n}function c(e,r,i){function a(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){l+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=a();if(l+=n(i.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=a();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(i.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(i,a){if(!i.compiled){if(i.compiled=!0,i.k=i.k||i.bK,i.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof i.k?c("keyword",i.k):E(i.k).forEach(function(e){c(e,i.k[e])}),i.k=u}i.lR=t(i.l||/\w+/,!0),a&&(i.bK&&(i.b="\\b("+i.bK.split(" ").join("|")+")\\b"),i.b||(i.b=/\B|\b/),i.bR=t(i.b),i.e||i.eW||(i.e=/\B|\b/),i.e&&(i.eR=t(i.e)),i.tE=n(i.e)||"",i.eW&&a.tE&&(i.tE+=(i.e?"|":"")+a.tE)),i.i&&(i.iR=t(i.i)),null==i.r&&(i.r=1),i.c||(i.c=[]);var s=[];i.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"===e?i:e)}),i.c=s,i.c.forEach(function(e){r(e,i)}),i.starts&&r(i.starts,a);var l=i.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([i.tE,i.i]).map(n).filter(Boolean);i.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,i,a){function o(e,n){var t,i;for(t=0,i=n.c.length;i>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!i&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var i=r?"":y.classPrefix,a='',a+n+o}function p(){var e,t,r,i;if(!E.k)return n(B);for(i="",t=0,E.lR.lastIndex=0,r=E.lR.exec(B);r;)i+=n(B.substring(t,r.index)),e=g(E,r),e?(M+=e[1],i+=h(e[0],n(r[0]))):i+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(B);return i+n(B.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!x[E.sL])return n(B);var t=e?l(E.sL,B,!0,L[E.sL]):f(B,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(L[E.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){k+=null!=E.sL?d():p(),B=""}function v(e){k+=e.cN?h(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(B+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?B+=n:(t.eB&&(B+=n),b(),t.rB||t.eB||(B=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var i=E;i.skip?B+=n:(i.rE||i.eE||(B+=n),b(),i.eE&&(B=n));do E.cN&&(k+=C),E.skip||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),i.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return B+=n,n.length||1}var N=R(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,E=a||N,L={},k="";for(w=E;w!==N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var B="",M=0;try{for(var I,j,O=0;;){if(E.t.lastIndex=O,I=E.t.exec(t),!I)break;j=m(t.substring(O,I.index),I[0]),O=I.index+j}for(m(t.substr(O)),w=E;w.parent;w=w.parent)w.cN&&(k+=C);return{r:M,value:k,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function f(e,t){t=t||y.languages||E(x);var r={r:0,value:n(e)},i=r;return t.filter(R).forEach(function(n){var t=l(n,e,!1);t.language=n,t.r>i.r&&(i=t),t.r>r.r&&(i=r,r=t)}),i.language&&(r.second_best=i),r}function g(e){return y.tabReplace||y.useBR?e.replace(M,function(e,n){return y.useBR&&"\n"===e?"
    ":y.tabReplace?n.replace(/\t/g,y.tabReplace):void 0}):e}function h(e,n,t){var r=n?L[n]:t,i=[e.trim()];return e.match(/\bhljs\b/)||i.push("hljs"),-1===e.indexOf(r)&&i.push(r),i.join(" ").trim()}function p(e){var n,t,r,o,s,p=a(e);i(p)||(y.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=p?l(p,s,!0):f(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=g(r.value),e.innerHTML=r.value,e.className=h(e.className,p,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function d(e){y=o(y,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");w.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function N(){return E(x)}function R(e){return e=(e||"").toLowerCase(),x[e]||x[L[e]]}var w=[],E=Object.keys,x={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
    ",y={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},I={"&":"&","<":"<",">":">"};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=R,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var i=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return i.c.push(e.PWM),i.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),i},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("gradle",function(e){return{cI:!0,k:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}}); \ No newline at end of file diff --git a/assets/javascripts/jquery-maven-artifact.min.js b/assets/javascripts/jquery-maven-artifact.min.js new file mode 100755 index 0000000..08a0304 --- /dev/null +++ b/assets/javascripts/jquery-maven-artifact.min.js @@ -0,0 +1,8 @@ +/** + * jQuery Maven Artifact Plugin + * + * Version: 1.0.1 + * Author: Jake Wharton + * License: Apache 2.0 + */ +(function($){function downloadUrl(groupId,artifactId,version,type){var groupPath=groupId.replace(/\./g,"/");return"http://repo1.maven.org/maven2/"+groupPath+"/"+artifactId+"/"+version+"/"+artifactId+"-"+version+type}$.fn.artifactVersion=function(groupId,artifactId,callback){if(typeof groupId!=="string"||typeof artifactId!=="string"){console.log("Error: groupId and artifactId are required.");return}if(typeof callback==="undefined"){console.log("Error: callback function required.");return}var url='http://search.maven.org/solrsearch/select/?q=g:"'+groupId+'"+AND+a:"'+artifactId+'"&wt=json&json.wrf=?';$.getJSON(url,function(response){var versions=response.response.docs;if(versions.length==0){return}var version=versions[0].latestVersion;var versionUrl=downloadUrl(groupId,artifactId,version,".jar");callback(version,versionUrl)})};$.fn.artifactVersions=function(groupId,artifactId,callback){if(typeof groupId!=="string"||typeof artifactId!=="string"){console.log("Error: groupId and artifactId are required.");return}if(typeof callback==="undefined"){console.log("Error: callback function required.");return}var url='http://search.maven.org/solrsearch/select/?q=g:"'+groupId+'"+AND+a:"'+artifactId+'"&wt=json&rows=10&core=gav&json.wrf=?';$.getJSON(url,function(response){var versions=response.response.docs;if(versions.length==0){return}versions.sort(function(o1,o2){return o1.v>o2.v?-1:1});var newVersions=[];for(var i=0;i0?e.push(this):(t[r](1),o=t[r]()>0,o&&e.push(this),t[r](0))}}),e.length||this.each(function(){"BODY"===this.nodeName&&(e=[this])}),"first"===t.el&&e.length>1&&(e=[e[0]]),e};l.fn.extend({scrollable:function(l){var t=r.call(this,{dir:l});return this.pushStack(t)},firstScrollable:function(l){var t=r.call(this,{el:"first",dir:l});return this.pushStack(t)},smoothScroll:function(e){e=e||{};var o=l.extend({},l.fn.smoothScroll.defaults,e),r=l.smoothScroll.filterPath(location.pathname);return this.unbind("click.smoothscroll").bind("click.smoothscroll",function(e){var n=this,s=l(this),c=o.exclude,i=o.excludeWithin,a=0,f=0,h=!0,u={},d=location.hostname===n.hostname||!n.hostname,m=o.scrollTarget||(l.smoothScroll.filterPath(n.pathname)||r)===r,p=t(n.hash);if(o.scrollTarget||d&&m&&p){for(;h&&c.length>a;)s.is(t(c[a++]))&&(h=!1);for(;h&&i.length>f;)s.closest(i[f++]).length&&(h=!1)}else h=!1;h&&(e.preventDefault(),l.extend(u,o,{scrollTarget:o.scrollTarget||p,link:n}),l.smoothScroll(u))}),this}}),l.smoothScroll=function(t,e){var o,r,n,s,c=0,i="offset",a="scrollTop",f={},h={};"number"==typeof t?(o=l.fn.smoothScroll.defaults,n=t):(o=l.extend({},l.fn.smoothScroll.defaults,t||{}),o.scrollElement&&(i="position","static"==o.scrollElement.css("position")&&o.scrollElement.css("position","relative"))),o=l.extend({link:null},o),a="left"==o.direction?"scrollLeft":a,o.scrollElement?(r=o.scrollElement,c=r[a]()):r=l("html, body").firstScrollable(),o.beforeScroll.call(r,o),n="number"==typeof t?t:e||l(o.scrollTarget)[i]()&&l(o.scrollTarget)[i]()[o.direction]||0,f[a]=n+c+o.offset,s=o.speed,"auto"===s&&(s=f[a]||r.scrollTop(),s/=o.autoCoefficent),h={duration:s,easing:o.easing,complete:function(){o.afterScroll.call(o.link,o)}},o.step&&(h.step=o.step),r.length?r.stop().animate(f,h):o.afterScroll.call(o.link,o)},l.smoothScroll.version=e,l.smoothScroll.filterPath=function(l){return l.replace(/^\//,"").replace(/(index|default).[a-zA-Z]{3,4}$/,"").replace(/\/$/,"")},l.fn.smoothScroll.defaults=o})(jQuery); \ No newline at end of file diff --git a/assets/stylesheets/app-theme.css b/assets/stylesheets/app-theme.css new file mode 100755 index 0000000..5a85cae --- /dev/null +++ b/assets/stylesheets/app-theme.css @@ -0,0 +1,51 @@ +/* http://www.colorhexa.com/48b982 */ + +/*** Primary ***/ + +header, +#subtitle, +a.dl { + background-color: #482B58; +} + +.content-nav li.active a, +.content-nav li.active a:hover { + border-left-color: #482B58; +} + +/*** One step left on the monochromatic scale ***/ + +header menu li a:hover, +a.dl:hover { + background-color: #f50; +} +header menu li a:visited, a:link { + color: #fff; + text-decoration: none; +} +p a, p a:visited, p a:link { + color: #f50; +} +p a:hover { + color: #482B58 +} + +/****************************************************************\ + **** Syntax highlighting styles ******************************** +\****************************************************************/ + +.pln { color: #000; } +.str { color: #32835b; } +.kwd { color: #666; } +.com { color: #800; } +.typ { color: #222; } +.lit { color: #666; } +.pun { color: #888; } +.opn { color: #888; } +.clo { color: #888; } +.tag { color: #32835b; } +.atn { color: #606; } +.atv { color: #080; } +.dec { color: #606; } +.var { color: #606; } +.fun { color: #f00; } diff --git a/assets/stylesheets/app.css b/assets/stylesheets/app.css new file mode 100755 index 0000000..a0e4b07 --- /dev/null +++ b/assets/stylesheets/app.css @@ -0,0 +1,216 @@ +html, body { + font-family: 'Roboto', sans-serif; + font-size: 15px; +} +body { + background-color: #f6f6f6; + padding-bottom: 50px; + padding-top: 80px; +} + +header { + min-height: 80px; + color: #f6f6f6; + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 99; +} +header h1 { + margin: 10px 0; + font-size: 50px; + line-height: 60px; + font-weight: 100; + text-rendering: auto; +} +header menu { + margin: 20px 0 0; + padding: 0; + height: 40px; +} +header menu ul { + margin: 0; + padding: 0; + float: right; +} +header menu li { + list-style: none; + float: left; + margin: 0; + padding: 0; +} +header menu li a { + display: inline-block; + height: 40px; + font-size: 17px; + line-height: 40px; + padding: 0 20px; + color: #f6f6f6; +} +header menu li a:hover { + color: #f6f6f6; + text-decoration: none; +} +header menu li a img { + margin: 0; + padding: 5px 0; + vertical-align: bottom; + width: 30px; + height: 30px; +} + +#subtitle { + position: absolute; + top: 80px; + left: 0; + width: 100%; +} +h2 { + font-weight: 200; + font-size: 26px; + line-height: 30px; + padding: 15px 0; + margin: 0; + color: #eee; +} +h2 strong { + font-weight: 300; +} + +.content-nav { + margin-top: 130px; + width: 220px; +} +.content-nav.affix { + top: 0; +} +.content-nav li.active a, .content-nav li.active a:hover { + background-color: transparent; + color: #555; + border-left-width: 2px; +} +.content-nav .secondary a { + color: #aaa; +} +.content-nav .secondary a:hover { + color: #888; +} + +.nav-tabs.nav-stacked { + border-left: 2px solid; + border-color: #f50; +} + +.nav-tabs.nav-stacked > li > a { + font-size: 18px; + color: #919191; + border: 0px; + border-radius: 0px !important; +} + +.nav-tabs.nav-stacked > li > a:hover { + color: #000; + font-weight: bolder; +} + +.nav-tabs.nav-stacked > li.active > a { + color: #000; + font-weight: bolder; + z-index: 0; + border: 0px; + background-color: #f6f6f6; +} + +hr { + display: block; + height: 2px; + border: 0; + border-top: 2px solid #e2e2e2; + margin-top: 0; + margin-bottom: 0; + margin-left: 5px; + padding: 0; +} + +h3 { + font-weight: bold; + color: #000; + font-size: 30px; + padding-top: 100px; + /* + Trick to fit scrolling by scrollspy from nav bar + http://stackoverflow.com/questions/9288482/how-do-i-set-the-offset-for-scrollspy-in-bootstrap + */ + margin-top: -70px; +} + +h4 { + font-weight: bold; + color: #333; + font-size: 25px; + padding-top: 20px; +} + +h5 { + font-weight: bold; + color: #333; + font-size: 18px; + padding-top: 10px; +} + +p.license { + font-family: fixed-width; +} + +.row .logo { + text-align: center; + margin-top: 100px; +} +.row .logo img { + height: 50px; +} +.line { + height: 5px; +} +.soundcloud-background-color { + background-color: #f50 +} + +/* Widescreen desktop. */ +@media (min-width: 1200px) { + .content-nav { + width: 270px; + } +} + +/* Smaller width browser, tablets. */ +@media (max-width: 979px) { + .content-nav { + width: 166px; + } +} + +/* One-column mobile display. */ +@media (max-width: 767px) { + header { + position: absolute; + top: 0; + left: 0; + width: 100%; + padding-left: 20px; + } + header menu { + display: none; + } + #subtitle { + position: absolute; + top: 80px; + left: 0; + width: 100%; + padding-left: 20px; + } + .content-nav { + display: none; + } +} diff --git a/assets/stylesheets/bootstrap-combined.min.css b/assets/stylesheets/bootstrap-combined.min.css new file mode 100755 index 0000000..1334dfa --- /dev/null +++ b/assets/stylesheets/bootstrap-combined.min.css @@ -0,0 +1,18 @@ +/*! + * Bootstrap v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} +/*! + * Bootstrap Responsive v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/assets/stylesheets/idea.css b/assets/stylesheets/idea.css new file mode 100644 index 0000000..3bf1892 --- /dev/null +++ b/assets/stylesheets/idea.css @@ -0,0 +1,97 @@ +/* + +Intellij Idea-like styling (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #000; + background: #fff; +} + +.hljs-subst, +.hljs-title { + font-weight: normal; + color: #000; +} + +.hljs-comment, +.hljs-quote { + color: #808080; + font-style: italic; +} + +.hljs-meta { + color: #808000; +} + +.hljs-tag { + background: #efefef; +} + +.hljs-section, +.hljs-name, +.hljs-literal, +.hljs-keyword, +.hljs-selector-tag, +.hljs-type, +.hljs-selector-id, +.hljs-selector-class { + font-weight: bold; + color: #000080; +} + +.hljs-attribute, +.hljs-number, +.hljs-regexp, +.hljs-link { + font-weight: bold; + color: #0000ff; +} + +.hljs-number, +.hljs-regexp, +.hljs-link { + font-weight: normal; +} + +.hljs-string { + color: #008000; + font-weight: bold; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-formula { + color: #000; + background: #d0eded; + font-style: italic; +} + +.hljs-doctag { + text-decoration: underline; +} + +.hljs-variable, +.hljs-template-variable { + color: #660e7a; +} + +.hljs-addition { + background: #baeeba; +} + +.hljs-deletion { + background: #ffc8bd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/build.gradle b/build.gradle deleted file mode 100644 index e6ce526..0000000 --- a/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -buildscript { - repositories { - mavenLocal() - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:2.2.2' - classpath 'com.netflix.nebula:gradle-extra-configurations-plugin:2.2.0' - } -} - -task wrapper(type: Wrapper) { - description 'Creates the gradle wrapper.' - gradleVersion '2.14.1' -} - -allprojects { - repositories { - mavenLocal() - jcenter() - } -} - -ext { - minSdkVersion = 9 - targetSdkVersion = 25 - compileSdkVersion = 25 - buildToolsVersion = '25.0.1' - sourceCompatibilityVersion = JavaVersion.VERSION_1_7 - targetCompatibilityVersion = JavaVersion.VERSION_1_7 -} - -def supportLibVersion = '25.0.1' - -ext.deps = [ - // Android - android : 'com.google.android:android:4.1.1.4', - support_v4 : 'com.google.android:support-v4:r7', - preference_v7 : "com.android.support:preference-v7:${supportLibVersion}", - appcompat_v7 : "com.android.support:appcompat-v7:${supportLibVersion}", - support_annotations : "com.android.support:support-annotations:${supportLibVersion}", - // Processor - javapoet : 'com.squareup:javapoet:1.6.1', - - // Test dependencies - junit : 'junit:junit:4.12', - mockito : 'org.mockito:mockito-all:1.10.19', - compiletesting : 'com.google.testing.compile:compile-testing:0.7', - roboelectric : 'org.robolectric:robolectric:3.1.2', - robolectric_support : 'org.robolectric:shadows-support-v4:3.1.2', -] - -// Static analysis -subprojects { project -> - apply plugin: 'checkstyle' - apply plugin: 'pmd' - apply plugin: 'findbugs' - - checkstyle { - toolVersion = "7.2" - configFile rootProject.file('checkstyle.xml') - } - - task checkstyle(type: Checkstyle) { - source 'src/main/java' - ignoreFailures false - showViolations true - include '**/*.java' - - classpath = files() - } - - task pmd(type: Pmd) { - description 'Finds common programming flaws throw static analysis of code.' - ignoreFailures false - } - - findbugs { - ignoreFailures = false - toolVersion = "3.0.0" - } - - tasks.withType(FindBugs) { - reports { - xml.enabled = false - html.enabled = true - } - } -} - -// configure Java projects -[":lightcycle-api", ":lightcycle-processor"].each { name -> - project(name) { - - apply plugin: 'provided-base' - apply plugin: 'java' - - sourceCompatibility = rootProject.ext.sourceCompatibilityVersion - targetCompatibility = rootProject.ext.targetCompatibilityVersion - } -} diff --git a/checkstyle.xml b/checkstyle.xml deleted file mode 100644 index b46ddd7..0000000 --- a/checkstyle.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/basic/.gitignore b/examples/basic/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/examples/basic/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/examples/basic/build.gradle b/examples/basic/build.gradle deleted file mode 100644 index 3202223..0000000 --- a/examples/basic/build.gradle +++ /dev/null @@ -1,36 +0,0 @@ -buildscript { - repositories { - jcenter() - } - dependencies { - // replace with the current version of the Android plugin - classpath 'com.android.tools.build:gradle:2.2.0' - } -} - -apply plugin: 'com.android.application' - -android { - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - - compileOptions { - sourceCompatibility rootProject.ext.sourceCompatibilityVersion - targetCompatibility rootProject.ext.targetCompatibilityVersion - } - - defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 - versionName "1.0" - } - -} - -dependencies { - annotationProcessor project(":lightcycle-processor") - - compile project(":lightcycle-lib") - compile deps.appcompat_v7 -} diff --git a/examples/basic/src/main/AndroidManifest.xml b/examples/basic/src/main/AndroidManifest.xml deleted file mode 100644 index d0f75d6..0000000 --- a/examples/basic/src/main/AndroidManifest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - diff --git a/examples/basic/src/main/java/com/soundcloud/lightcycle/sample/basic/ActivityLogger.java b/examples/basic/src/main/java/com/soundcloud/lightcycle/sample/basic/ActivityLogger.java deleted file mode 100644 index af99383..0000000 --- a/examples/basic/src/main/java/com/soundcloud/lightcycle/sample/basic/ActivityLogger.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.soundcloud.lightcycle.sample.basic; - - -import com.soundcloud.lightcycle.DefaultActivityLightCycle; - -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.util.Log; - -class ActivityLogger extends DefaultActivityLightCycle { - - private static final String TAG = "ACTIVITY_LOG"; - - @Override - public void onCreate(AppCompatActivity activity, Bundle bundle) { - Log.i(TAG, "Creating activity:" + activity); - } - - @Override - public void onStart(AppCompatActivity activity) { - Log.i(TAG, "Starting activity:" + activity); - } - - @Override - public void onResume(AppCompatActivity activity) { - Log.i(TAG, "Resuming activity:" + activity); - } - - @Override - public void onPause(AppCompatActivity activity) { - Log.i(TAG, "Pausing activity:" + activity); - } - - @Override - public void onStop(AppCompatActivity activity) { - Log.i(TAG, "Stopping activity:" + activity); - } - - @Override - public void onDestroy(AppCompatActivity activity) { - Log.i(TAG, "Destroying activity:" + activity); - } -} diff --git a/examples/basic/src/main/java/com/soundcloud/lightcycle/sample/basic/SampleActivity.java b/examples/basic/src/main/java/com/soundcloud/lightcycle/sample/basic/SampleActivity.java deleted file mode 100644 index 97654f3..0000000 --- a/examples/basic/src/main/java/com/soundcloud/lightcycle/sample/basic/SampleActivity.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.soundcloud.lightcycle.sample.basic; - -import com.soundcloud.lightcycle.LightCycle; -import com.soundcloud.lightcycle.LightCycleAppCompatActivity; - -public class SampleActivity extends LightCycleAppCompatActivity { - @LightCycle ActivityLogger activityLogger = new ActivityLogger(); - - @Override - protected void setActivityContentView() { - setContentView(R.layout.activity_sample); - } -} diff --git a/examples/basic/src/main/res/layout/activity_sample.xml b/examples/basic/src/main/res/layout/activity_sample.xml deleted file mode 100644 index bf14ff5..0000000 --- a/examples/basic/src/main/res/layout/activity_sample.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/examples/basic/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/basic/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bc..0000000 Binary files a/examples/basic/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/examples/basic/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/basic/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0c..0000000 Binary files a/examples/basic/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/examples/basic/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/basic/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0..0000000 Binary files a/examples/basic/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/basic/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/basic/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72c..0000000 Binary files a/examples/basic/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/basic/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/basic/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index aee44e1..0000000 Binary files a/examples/basic/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/basic/src/main/res/values/colors.xml b/examples/basic/src/main/res/values/colors.xml deleted file mode 100644 index 95af1ff..0000000 --- a/examples/basic/src/main/res/values/colors.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - #ffffff - #bbbbbb - @color/soundcloud - #ff5500 - diff --git a/examples/basic/src/main/res/values/strings.xml b/examples/basic/src/main/res/values/strings.xml deleted file mode 100644 index a04717a..0000000 --- a/examples/basic/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - LightCycle Basic example. - diff --git a/examples/basic/src/main/res/values/styles.xml b/examples/basic/src/main/res/values/styles.xml deleted file mode 100644 index c62b553..0000000 --- a/examples/basic/src/main/res/values/styles.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/examples/real-world/.gitignore b/examples/real-world/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/examples/real-world/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/examples/real-world/build.gradle b/examples/real-world/build.gradle deleted file mode 100644 index cee64f9..0000000 --- a/examples/real-world/build.gradle +++ /dev/null @@ -1,41 +0,0 @@ -buildscript { - repositories { - jcenter() - } - dependencies { - // replace with the current version of the Android plugin - classpath 'com.android.tools.build:gradle:2.2.2' - } -} - -apply plugin: 'com.android.application' - -android { - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - - compileOptions { - sourceCompatibility rootProject.ext.sourceCompatibilityVersion - targetCompatibility rootProject.ext.targetCompatibilityVersion - } - - defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 - versionName "1.0" - } -} - -dependencies { - annotationProcessor project(":lightcycle-processor") - compile project(":lightcycle-lib") - - annotationProcessor "com.squareup.dagger:dagger-compiler:1.2.2" - compile "com.squareup.dagger:dagger:1.2.2" - - compile deps.appcompat_v7 - - testCompile deps.junit - testCompile deps.mockito -} diff --git a/examples/real-world/src/main/AndroidManifest.xml b/examples/real-world/src/main/AndroidManifest.xml deleted file mode 100644 index 6696233..0000000 --- a/examples/real-world/src/main/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/ApplicationModule.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/ApplicationModule.java deleted file mode 100644 index f38875e..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/ApplicationModule.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import dagger.Module; -import dagger.Provides; - -import java.util.Calendar; - -@Module(injects = {HomeActivity.class, LicenseFragment.class}) -class ApplicationModule { - - @Provides Calendar provideCalendar() { - return Calendar.getInstance(); - } -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/DescriptionPresenter.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/DescriptionPresenter.java deleted file mode 100644 index b28fa2b..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/DescriptionPresenter.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import com.soundcloud.lightcycle.DefaultActivityLightCycle; - -import android.os.Bundle; -import android.support.annotation.Nullable; - -import javax.inject.Inject; - -class DescriptionPresenter extends DefaultActivityLightCycle { - - @Inject - public DescriptionPresenter() {} - - @Override - public void onCreate(HomeActivity activity, @Nullable Bundle bundle) { - activity.showDescription("LightCycle", "https://github.com/soundcloud/lightcycle"); - } - -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HeaderPresenter.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HeaderPresenter.java deleted file mode 100644 index b16443b..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HeaderPresenter.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import com.soundcloud.lightcycle.DefaultActivityLightCycle; -import com.soundcloud.lightcycle.sample.real_world.utils.DateProvider; - -import android.os.Bundle; -import android.support.annotation.Nullable; - -import javax.inject.Inject; - -class HeaderPresenter extends DefaultActivityLightCycle { - private final DateProvider dateProvider; - - @Inject - public HeaderPresenter(DateProvider dateProvider) { - this.dateProvider = dateProvider; - } - - @Override - public void onCreate(HomeActivity activity, @Nullable Bundle bundle) { - if (dateProvider.isMorning()) { - activity.sayHello(R.string.good_morning); - } else { - activity.sayHello(R.string.hello); - } - } - -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HomeActivity.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HomeActivity.java deleted file mode 100644 index 24221e4..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HomeActivity.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import com.soundcloud.lightcycle.LightCycle; -import com.soundcloud.lightcycle.LightCycleAppCompatActivity; -import com.soundcloud.lightcycle.sample.real_world.tracker.Screen; -import com.soundcloud.lightcycle.sample.real_world.tracker.ScreenTracker; - -import android.support.annotation.StringRes; -import android.widget.TextView; - -import javax.inject.Inject; - -public class HomeActivity extends LightCycleAppCompatActivity implements Screen { - @Inject @LightCycle ScreenTracker screenTracker; - @Inject @LightCycle HomePresenter headerPresenter; - - public HomeActivity() { - SampleApp.getObjectGraph().inject(this); - } - - @Override - public String getScreenName() { - return "HomeActivity"; - } - - @Override - protected void setActivityContentView() { - setContentView(R.layout.activity_home); - } - - void sayHello(@StringRes int hello) { - ((TextView) findViewById(R.id.hello)).setText(hello); - } - - void showDescription(String title, String description) { - ((TextView) findViewById(R.id.title)).setText(title); - ((TextView) findViewById(R.id.description)).setText(description); - } -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HomePresenter.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HomePresenter.java deleted file mode 100644 index 97fc841..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/HomePresenter.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import com.soundcloud.lightcycle.ActivityLightCycleDispatcher; -import com.soundcloud.lightcycle.LightCycle; -import com.soundcloud.lightcycle.LightCycles; - -import android.os.Bundle; -import android.support.annotation.Nullable; - -import javax.inject.Inject; - -class HomePresenter extends ActivityLightCycleDispatcher { - @LightCycle final HeaderPresenter headerPresenter; - @LightCycle final DescriptionPresenter descriptionPresenter; - - @Inject - HomePresenter(HeaderPresenter headerPresenter, DescriptionPresenter descriptionPresenter) { - this.headerPresenter = headerPresenter; - this.descriptionPresenter = descriptionPresenter; - } - - @Override - public void onCreate(HomeActivity activity, @Nullable Bundle bundle) { - LightCycles.bind(this); - super.onCreate(activity, bundle); - } -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/LicenseFragment.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/LicenseFragment.java deleted file mode 100644 index e46cdd1..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/LicenseFragment.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import com.soundcloud.lightcycle.LightCycle; -import com.soundcloud.lightcycle.LightCycleSupportFragment; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import javax.inject.Inject; - -public class LicenseFragment extends LightCycleSupportFragment { - @Inject @LightCycle LicensePresenter descriptionPresenter; - - public LicenseFragment() { - SampleApp.getObjectGraph().inject(this); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_license, container, false); - } - - void showLicense(String readme) { - ((TextView) getView().findViewById(R.id.license)).setText(readme); - } - -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/LicensePresenter.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/LicensePresenter.java deleted file mode 100644 index 4898aea..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/LicensePresenter.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import com.soundcloud.lightcycle.DefaultSupportFragmentLightCycle; - -import android.os.Bundle; -import android.view.View; - -import javax.inject.Inject; - -class LicensePresenter extends DefaultSupportFragmentLightCycle { - - @Inject - public LicensePresenter() { - } - - @Override - public void onViewCreated(LicenseFragment fragment, View view, Bundle savedInstanceState) { - fragment.showLicense("Apache License 2.0"); - } -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/SampleApp.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/SampleApp.java deleted file mode 100644 index 5daa078..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/SampleApp.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import dagger.ObjectGraph; - -import android.app.Application; - -public class SampleApp extends Application { - - private static SampleApp instance; - - protected ObjectGraph objectGraph; - - @Override - public void onCreate() { - super.onCreate(); - objectGraph = ObjectGraph.create(new ApplicationModule()); - instance = this; - } - - public static ObjectGraph getObjectGraph() { - if (instance == null || instance.objectGraph == null) { - throw new IllegalStateException("Cannot access the app graph before the application has been created"); - } - return instance.objectGraph; - } -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/Screen.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/Screen.java deleted file mode 100644 index 32f18eb..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/Screen.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world.tracker; - -public interface Screen { - String getScreenName(); - -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/ScreenTracker.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/ScreenTracker.java deleted file mode 100644 index 292327d..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/ScreenTracker.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world.tracker; - -import com.soundcloud.lightcycle.DefaultActivityLightCycle; -import com.soundcloud.lightcycle.sample.real_world.HomeActivity; - -import javax.inject.Inject; - -public class ScreenTracker extends DefaultActivityLightCycle { - - private final TrackingOperations operations; - - @Inject - public ScreenTracker(TrackingOperations operations) { - this.operations = operations; - } - - @Override - public void onResume(HomeActivity activity) { - operations.trackScreen(activity); - } -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/TrackingOperations.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/TrackingOperations.java deleted file mode 100644 index a72c4fb..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/tracker/TrackingOperations.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world.tracker; - -import javax.inject.Inject; - -public class TrackingOperations { - @Inject - public TrackingOperations() { - } - - public void trackScreen(Screen screen) { - System.out.println("Tracking screen:" + screen.getScreenName()); - } - -} diff --git a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/utils/DateProvider.java b/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/utils/DateProvider.java deleted file mode 100644 index e72633c..0000000 --- a/examples/real-world/src/main/java/com/soundcloud/lightcycle/sample/real_world/utils/DateProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world.utils; - -import android.support.annotation.VisibleForTesting; - -import javax.inject.Inject; -import java.util.Calendar; - -public class DateProvider { - - private final Calendar calendar; - - @Inject - public DateProvider(Calendar calendar) { - this.calendar = calendar; - } - - @VisibleForTesting - public DateProvider() { - this.calendar = null; - } - - - public long currentTimeMillis() { - return System.currentTimeMillis(); - } - - public boolean isMorning() { - final int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); - return hourOfDay >= 0 && hourOfDay < 12; - } -} diff --git a/examples/real-world/src/main/res/layout/activity_home.xml b/examples/real-world/src/main/res/layout/activity_home.xml deleted file mode 100644 index 061ee6a..0000000 --- a/examples/real-world/src/main/res/layout/activity_home.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - diff --git a/examples/real-world/src/main/res/layout/fragment_license.xml b/examples/real-world/src/main/res/layout/fragment_license.xml deleted file mode 100644 index 3687a45..0000000 --- a/examples/real-world/src/main/res/layout/fragment_license.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/examples/real-world/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/real-world/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bc..0000000 Binary files a/examples/real-world/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/examples/real-world/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/real-world/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0c..0000000 Binary files a/examples/real-world/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/examples/real-world/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/real-world/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0..0000000 Binary files a/examples/real-world/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/real-world/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/real-world/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72c..0000000 Binary files a/examples/real-world/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/real-world/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/real-world/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index aee44e1..0000000 Binary files a/examples/real-world/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/real-world/src/main/res/values/colors.xml b/examples/real-world/src/main/res/values/colors.xml deleted file mode 100644 index 95af1ff..0000000 --- a/examples/real-world/src/main/res/values/colors.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - #ffffff - #bbbbbb - @color/soundcloud - #ff5500 - diff --git a/examples/real-world/src/main/res/values/strings.xml b/examples/real-world/src/main/res/values/strings.xml deleted file mode 100644 index adb4ac6..0000000 --- a/examples/real-world/src/main/res/values/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - LightCycle \"real world\" example. - Good morning - Hello - diff --git a/examples/real-world/src/main/res/values/styles.xml b/examples/real-world/src/main/res/values/styles.xml deleted file mode 100644 index c62b553..0000000 --- a/examples/real-world/src/main/res/values/styles.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/HeaderPresenterTest.java b/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/HeaderPresenterTest.java deleted file mode 100644 index ef845a4..0000000 --- a/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/HeaderPresenterTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world; - -import static org.mockito.Mockito.verify; - -import com.soundcloud.lightcycle.sample.real_world.utils.DateProvider; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import android.os.Bundle; - -@RunWith(MockitoJUnitRunner.class) -public class HeaderPresenterTest { - @Mock private HomeActivity activity; - - @Test - public void sayHelloWhenNotMorning() { - HeaderPresenter presenter = new HeaderPresenter(new DateProvider() { - @Override - public boolean isMorning() { - return false; - } - }); - - presenter.onCreate(activity, Bundle.EMPTY); - - verify(activity).sayHello(R.string.hello); - } - - @Test - public void sayGoodMorning() { - HeaderPresenter presenter = new HeaderPresenter(new DateProvider() { - @Override - public boolean isMorning() { - return true; - } - }); - - presenter.onCreate(activity, Bundle.EMPTY); - - verify(activity).sayHello(R.string.good_morning); - } -} diff --git a/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/tracker/ScreenTrackerTest.java b/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/tracker/ScreenTrackerTest.java deleted file mode 100644 index f01bb3c..0000000 --- a/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/tracker/ScreenTrackerTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world.tracker; - -import static org.mockito.Mockito.verify; - -import com.soundcloud.lightcycle.sample.real_world.HomeActivity; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class ScreenTrackerTest { - - @Mock private TrackingOperations operations; - @Mock private HomeActivity activity; - private ScreenTracker tracker; - - @Before - public void setUp() throws Exception { - tracker = new ScreenTracker(operations); - } - - @Test - public void trackScreenOnResume() { - tracker.onResume(activity); - - verify(operations).trackScreen(activity); - } -} diff --git a/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/utils/DateProviderTest.java b/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/utils/DateProviderTest.java deleted file mode 100644 index 97b1b66..0000000 --- a/examples/real-world/src/test/java/com/soundcloud/lightcycle/sample/real_world/utils/DateProviderTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.soundcloud.lightcycle.sample.real_world.utils; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.when; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import java.util.Calendar; - -@RunWith(MockitoJUnitRunner.class) -public class DateProviderTest { - private DateProvider dateProvider; - @Mock private Calendar calendar; - - @Before - public void setUp() throws Exception { - dateProvider = new DateProvider(calendar); - } - - @Test - public void midnightIsMorning() { - when(calendar.get(Calendar.HOUR_OF_DAY)).thenReturn(0); - - assertThat(dateProvider.isMorning(), is(true)); - } - - @Test - public void lunchTimeIsNotAnyMoreMorning() { - when(calendar.get(Calendar.HOUR_OF_DAY)).thenReturn(12); - - assertThat(dateProvider.isMorning(), is(false)); - } - - @Test - public void dinerTimeIsNotMorning() { - when(calendar.get(Calendar.HOUR_OF_DAY)).thenReturn(20); - - assertThat(dateProvider.isMorning(), is(false)); - } - -} diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index bb2596e..0000000 --- a/gradle.properties +++ /dev/null @@ -1,14 +0,0 @@ -VERSION_NAME=1.5.0 -VERSION_CODE=0 -GROUP=com.soundcloud.lightcycle - -POM_DESCRIPTION=LightCycle lets self-contained classes respond to Android’s lifecycle events -POM_URL=https://github.com/soundcloud/lightcycle -POM_SCM_URL=https://github.com/soundcloud/lightcycle -POM_SCM_CONNECTION=scm:git@github.com:soundcloud/lightcycle.git -POM_SCM_DEV_CONNECTION=scm:git@github.com:soundcloud/lightcycle.git -POM_LICENCE_NAME=The Apache Software License, Version 2.0 -POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt -POM_LICENCE_DIST=repo -POM_DEVELOPER_ID=SoundCloud -POM_DEVELOPER_NAME=SoundCloud diff --git a/gradle/gradle-mvn-push.gradle b/gradle/gradle-mvn-push.gradle deleted file mode 100644 index 71c2bab..0000000 --- a/gradle/gradle-mvn-push.gradle +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2013 Chris Banes - * - * 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. - */ - -apply plugin: 'maven' -apply plugin: 'signing' - -version = VERSION_NAME -group = GROUP - -def isReleaseBuild() { - return VERSION_NAME.contains("SNAPSHOT") == false -} - -def getReleaseRepositoryUrl() { - return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL - : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" -} - -def getSnapshotRepositoryUrl() { - return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL - : "https://oss.sonatype.org/content/repositories/snapshots/" -} - -def getRepositoryUsername() { - return hasProperty('SONATYPE_NEXUS_USERNAME') ? SONATYPE_NEXUS_USERNAME : "" -} - -def getRepositoryPassword() { - return hasProperty('SONATYPE_NEXUS_PASSWORD') ? SONATYPE_NEXUS_PASSWORD : "" -} - -afterEvaluate { project -> - uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - pom.groupId = GROUP - pom.artifactId = POM_ARTIFACT_ID - pom.version = VERSION_NAME - - repository(url: getReleaseRepositoryUrl()) { - authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) - } - snapshotRepository(url: getSnapshotRepositoryUrl()) { - authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) - } - - pom.project { - name POM_NAME - packaging POM_PACKAGING - description POM_DESCRIPTION - url POM_URL - - scm { - url POM_SCM_URL - connection POM_SCM_CONNECTION - developerConnection POM_SCM_DEV_CONNECTION - } - - licenses { - license { - name POM_LICENCE_NAME - url POM_LICENCE_URL - distribution POM_LICENCE_DIST - } - } - - developers { - developer { - id POM_DEVELOPER_ID - name POM_DEVELOPER_NAME - } - } - } - } - } - } - - signing { - required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } - sign configurations.archives - } - - if (project.getPlugins().hasPlugin('com.android.application') || - project.getPlugins().hasPlugin('com.android.library')) { - task install(type: Upload, dependsOn: assemble) { - repositories.mavenInstaller { - configuration = configurations.archives - - pom.groupId = GROUP - pom.artifactId = POM_ARTIFACT_ID - pom.version = VERSION_NAME - - pom.project { - name POM_NAME - packaging POM_PACKAGING - description POM_DESCRIPTION - url POM_URL - - scm { - url POM_SCM_URL - connection POM_SCM_CONNECTION - developerConnection POM_SCM_DEV_CONNECTION - } - - licenses { - license { - name POM_LICENCE_NAME - url POM_LICENCE_URL - distribution POM_LICENCE_DIST - } - } - - developers { - developer { - id POM_DEVELOPER_ID - name POM_DEVELOPER_NAME - } - } - } - } - } - - task androidJavadocs(type: Javadoc) { - source = android.sourceSets.main.java.source - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - } - - task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { - classifier = 'javadoc' - from androidJavadocs.destinationDir - } - - task androidSourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.source - } - } else { - install { - repositories.mavenInstaller { - pom.groupId = GROUP - pom.artifactId = POM_ARTIFACT_ID - pom.version = VERSION_NAME - - pom.project { - name POM_NAME - packaging POM_PACKAGING - description POM_DESCRIPTION - url POM_URL - - scm { - url POM_SCM_URL - connection POM_SCM_CONNECTION - developerConnection POM_SCM_DEV_CONNECTION - } - - licenses { - license { - name POM_LICENCE_NAME - url POM_LICENCE_URL - distribution POM_LICENCE_DIST - } - } - - developers { - developer { - id POM_DEVELOPER_ID - name POM_DEVELOPER_NAME - } - } - } - } - } - - task sourcesJar(type: Jar, dependsOn:classes) { - classifier = 'sources' - from sourceSets.main.allSource - } - - task javadocJar(type: Jar, dependsOn:javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir - } - } - - if (JavaVersion.current().isJava8Compatible()) { - allprojects { - tasks.withType(Javadoc) { - options.addStringOption('Xdoclint:none', '-quiet') - } - } - } - - artifacts { - if (project.getPlugins().hasPlugin('com.android.application') || - project.getPlugins().hasPlugin('com.android.library')) { - archives androidSourcesJar - archives androidJavadocsJar - } else { - archives sourcesJar - archives javadocJar - } - } -} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 13372ae..0000000 Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 4e3f763..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Sun Nov 13 16:29:51 JST 2016 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/gradlew b/gradlew deleted file mode 100755 index 9d82f78..0000000 --- a/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index aec9973..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/index.html b/index.html new file mode 100755 index 0000000..9687b75 --- /dev/null +++ b/index.html @@ -0,0 +1,296 @@ + + + + + Lightcycle + + + + + + + + + +
    +
    +
    +
    +
    +

    LightCycle

    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +

    Self-contained components that helps break logic out of Activity and Fragment

    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +

    Introduction

    +

    LightCycle is an Android library that helps break logic out of Activity and Fragment classes into small, self-contained components called LightCycles.

    +

    Fields that are annotated @LightCycle and implement the LightCycle API within a LightCycleActivity or LightCycleFragment will be bound to that Activity or Fragment lifecycle.

    + +

    LightCycle lets self-contained classes respond to Android’s lifecycle events. + This supports composition over inheritance and promotes components that follow the single responsibility principle. + We believe it helps us write more readable, maintainable and testable code. + It works particularly well alongside dependency injection.

    + +

    ● Activity and Fragment classes:
    +     ○ Inflate layouts and configure Android specifics
    +     ○ Declare LightCycles
    + ● A LightCycle component is responsible for an isolated chunk of logic (such as presentation, tracking etc.)

    + +

    A LightCycle doesn't know about other LightCycles. There is no guarantee for ordering when multiple LightCycles receive the same lifecycle callback.

    + +

    Usage

    +

    Do your view initialization in your Activity

    +
    public class MyActivity extends LightCycleAppCompatActivity {
    +    @LightCycle MyController controller = new MyController();
    +
    +    @Override
    +    protected void setActivityContentView() {
    +        setContentView(R.layout.main);
    +    }
    +}
    +

    And put your logic inside your LightCycle

    +
    public class MyController extends DefaultActivityLightCycle {
    +
    +    @Override
    +    public void onPause(MyActivity activity) {
    +        // MyActivity was paused
    +    }
    +
    +    [...]
    +
    +    @Override
    +    public void onResume(MyActivity activity) {
    +        // MyActivity was resumed
    +    }
    +}
    +
    + +
    +

    Examples

    +

    Basic

    +

    "Real World"

    +
    + +
    +

    Documentation

    +

    LightCycle

    +

    There are 3 types of LightCycles - the API is comparable to the ActivityLifecycleCallbacks from the Android SDK:

    +

    ActivityLightCycle
    + ● FragmentLightCycle
    + ● SupportFragmentLightCycle

    +

    For convenience, default implementations are provided:

    +

    DefaultActivityLightCycle
    + ● DefaultFragmentLightCycle
    + ● DefaultSupportFragmentLightCycle

    + +

    Dispatcher

    +

    This dispatches an Activity or Fragment lifecycle callback to attached LightCycles. The API defines a single bind method. See the LightCycleDispatcher interface.

    +
    Built-in dispatchers
    +

    Three types of dispatchers are provided:

    +

    ActivityLightCycleDispatcher
    + ● FragmentLightCycleDispatcher
    + ● SupportFragmentLightCycleDispatcher

    +

    Note: these built-in classes are both dispatchers and LightCycles, meaning that you can nest LightCycles.

    +

    Do your view initialization in your activity as usual

    +
    public class MyActivity extends LightCycleAppCompatActivity {
    +    @LightCycle MyController controller = new MyController();
    +
    +    @Override
    +    protected void setActivityContentView() {
    +        setContentView(R.layout.main);
    +    }
    +}
    +

    Extend your logic class to matching Dispatcher class based on the type + (Activity with ActivityLightCycleDispatcher, Fragment with FragmentLightCycleDispatcher, etc) + and then you can nest another LightCycles too inside your Dispatcher

    +
    public class MyController extends ActivityLightCycleDispatcher {
    +    @LightCycle MySubController1 controller = new MyController1();
    +    @LightCycle MySubController2 controller = new MyController2();
    +
    +    @Override
    +    public void onCreate(Bundle savedInstanceState) {
    +        [...] // <- specific init
    +        super.onCreate(savedInstanceState) // <- call super to dispatch.
    +    }
    +}
    + +
    Provided base dispatcher classes
    +

    The following base dispatcher classes are provided so far:

    +

    LightCycleActivity
    + ● LightCycleAppCompatActivity
    + ● LightCycleActionBarActivity
    + ● LightCycleFragment
    + ● LightCycleSupportFragment
    + ● LightCycleSupportDialogFragment
    + ● LightCyclePreferenceFragmentCompat

    + +

    Known Limitation

    +
    Creating your own base dispatcher class
    +

    ⚠ Please, read carefully the following steps (item 2 in particular). ⚠

    +

    To add LightCycles to your MyBaseActivity, your Activity must:

    +

    ● Implement the LightCycleDispatcher interface. + Note: The processor needs to know the exact type being dispatched, + so if your base activity is templated then the activities inheriting + from it must explicitly implements LightCycleDispatcher> + (for more details, refer to this issue)
    + ● Dispatch all the lifecycle methods
    + ● Bind fields annotated @LightCycle with LightCycles.bind(this) +

    +

    The same technique applies for Fragment.

    +

    Example

    + +
    public class MyBaseActivity extends Activity implements LightCycleDispatcher> {
    +
    +    private final ActivityLightCycleDispatcher lightCycleDispatcher;
    +
    +    @Override
    +    public void bind(ActivityLightCycle lightCycle) {
    +        lightCycleDispatcher.bind(lightCycle);
    +    }
    +
    +    @Override
    +    protected void onCreate(Bundle savedInstanceState) {
    +        super.onCreate(savedInstanceState);
    +        LightCycles.bind(this);
    +        lightCycleDispatcher.onCreate((MyBaseActivity) this, savedInstanceState);
    +    }
    +
    +    [...]
    +
    +    @Override
    +    protected void onDestroy() {
    +        lightCycleDispatcher.onDestroy((MyBaseActivity) this);
    +        super.onDestroy();
    +    }
    +}
    +

    See LightCycleActionBarActivity + and LightCycleSupportFragment for example

    +
    + +
    +

    Download

    +

    You can check full source code of LightCycle on GitHub.

    + +

    Gradle

    +
    dependencies {
    +  compile 'com.soundcloud.lightcycle:lightcycle-lib:(insert latest version)'
    +  annotationProcessor 'com.soundcloud.lightcycle:lightcycle-processor:(insert latest version)'
    +}
    +

    Or if you're using a version of the Android gradle plugin below 2.2.0

    +
    buildscript {
    +  dependencies {
    +    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    +  }
    +}
    +
    +apply plugin: 'com.neenbedankt.android-apt'
    +
    +ext.lightCycleVersion=
    +
    +  dependencies {
    +  compile 'com.soundcloud.lightcycle:lightcycle-lib:(insert latest version)'
    +  apt 'com.soundcloud.lightcycle:lightcycle-processor:(insert latest version)'
    +}
    +
    + +
    +

    License

    +
    Copyright 2016 SoundCloud Limited
    +
    +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.
    +
    +
    + +
    +
    + +
    +
    +
    + + + + + + + + + diff --git a/lightcycle-api/build.gradle b/lightcycle-api/build.gradle deleted file mode 100644 index 6138869..0000000 --- a/lightcycle-api/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'checkstyle' -apply from: rootProject.file('gradle/gradle-mvn-push.gradle') - -checkstyle { - configFile rootProject.file('checkstyle.xml') - showViolations true -} - -dependencies { - provided deps.android - provided deps.support_v4 -} diff --git a/lightcycle-api/gradle.properties b/lightcycle-api/gradle.properties deleted file mode 100644 index dc1b16e..0000000 --- a/lightcycle-api/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -POM_NAME=LightCycle API -POM_ARTIFACT_ID=lightcycle-api -POM_PACKAGING=jar diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/ActivityLightCycle.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/ActivityLightCycle.java deleted file mode 100644 index 274a646..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/ActivityLightCycle.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.MenuItem; - -public interface ActivityLightCycle { - void onCreate(T activity, Bundle bundle); - void onNewIntent(T activity, Intent intent); - void onStart(T activity); - void onResume(T activity); - boolean onOptionsItemSelected(T activity, MenuItem item); - void onPause(T activity); - void onStop(T activity); - void onSaveInstanceState(T activity, Bundle bundle); - void onRestoreInstanceState(T activity, Bundle bundle); - void onDestroy(T activity); -} diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultActivityLightCycle.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultActivityLightCycle.java deleted file mode 100644 index 6963209..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultActivityLightCycle.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.MenuItem; - -public class DefaultActivityLightCycle implements ActivityLightCycle { - @Override - public void onCreate(T activity, Bundle bundle) { /* no-op */ } - - @Override - public void onNewIntent(T activity, Intent intent) { /* no-op */ } - - @Override - public void onStart(T activity) { /* no-op */ } - - @Override - public void onResume(T activity) { /* no-op */ } - - @Override - public boolean onOptionsItemSelected(T activity, MenuItem item) { - return false; - } - - @Override - public void onPause(T activity) { /* no-op */ } - - @Override - public void onStop(T activity) { /* no-op */ } - - @Override - public void onSaveInstanceState(T activity, Bundle bundle) { /* no-op */ } - - @Override - public void onRestoreInstanceState(T activity, Bundle bundle) { /* no-op */ } - - @Override - public void onDestroy(T activity) { /* no-op */ } -} diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultFragmentLightCycle.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultFragmentLightCycle.java deleted file mode 100644 index 650a1f1..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultFragmentLightCycle.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.Fragment; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; - -@TargetApi(Build.VERSION_CODES.HONEYCOMB) -public class DefaultFragmentLightCycle implements FragmentLightCycle { - @Override - public void onAttach(T fragment, Activity activity) { /* no-op */ } - - @Override - public void onAttach(T fragment, Context context) { /* no-op */ } - - @Override - public void onCreate(T fragment, Bundle bundle) { /* no-op */ } - - @Override - public void onViewCreated(T fragment, View view, Bundle savedInstanceState) { /* no-op */ } - - @Override - public void onActivityCreated(T fragment, Bundle bundle) { /* no-op */ } - - @Override - public void onStart(T fragment) { /* no-op */ } - - @Override - public void onResume(T fragment) { /* no-op */ } - - @Override - public boolean onOptionsItemSelected(T fragment, MenuItem item) { - return false; - } - - @Override - public void onPause(T fragment) { /* no-op */ } - - @Override - public void onStop(T fragment) { /* no-op */ } - - @Override - public void onSaveInstanceState(T fragment, Bundle bundle) { /* no-op */ } - - @Override - public void onDestroyView(T fragment) { /* no-op */ } - - @Override - public void onDestroy(T fragment) { /* no-op */ } - - @Override - public void onDetach(T fragment) { /* no-op */ } -} diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultSupportFragmentLightCycle.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultSupportFragmentLightCycle.java deleted file mode 100644 index bfe1ab0..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/DefaultSupportFragmentLightCycle.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.MenuItem; -import android.view.View; - -public class DefaultSupportFragmentLightCycle implements SupportFragmentLightCycle { - @Override - public void onAttach(T fragment, Activity activity) { /* no-op */ } - - @Override - public void onCreate(T fragment, Bundle bundle) { /* no-op */ } - - @Override - public void onViewCreated(T fragment, View view, Bundle savedInstanceState) { /* no-op */ } - - @Override - public void onActivityCreated(T fragment, Bundle bundle) { /* no-op */ } - - @Override - public void onStart(T fragment) { /* no-op */ } - - @Override - public void onResume(T fragment) { /* no-op */ } - - @Override - public boolean onOptionsItemSelected(T fragment, MenuItem item) { - return false; - } - - @Override - public void onPause(T fragment) { /* no-op */ } - - @Override - public void onStop(T fragment) { /* no-op */ } - - @Override - public void onSaveInstanceState(T fragment, Bundle bundle) { /* no-op */ } - - @Override - public void onDestroyView(T fragment) { /* no-op */ } - - @Override - public void onDestroy(T fragment) { /* no-op */ } - - @Override - public void onDetach(T fragment) { /* no-op */ } -} diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/FragmentLightCycle.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/FragmentLightCycle.java deleted file mode 100644 index 9439fac..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/FragmentLightCycle.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.Fragment; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; - -@TargetApi(Build.VERSION_CODES.HONEYCOMB) -public interface FragmentLightCycle { - void onAttach(T fragment, Activity activity); - @TargetApi(23) - void onAttach(T fragment, Context context); - void onCreate(T fragment, Bundle bundle); - void onViewCreated(T fragment, View view, Bundle savedInstanceState); - void onActivityCreated(T fragment, Bundle bundle); - void onStart(T fragment); - void onResume(T fragment); - boolean onOptionsItemSelected(T fragment, MenuItem item); - void onPause(T fragment); - void onStop(T fragment); - void onSaveInstanceState(T fragment, Bundle bundle); - void onDestroyView(T fragment); - void onDestroy(T fragment); - void onDetach(T fragment); -} diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycle.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycle.java deleted file mode 100644 index ac5d06b..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycle.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.soundcloud.lightcycle; - - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.SOURCE) -@Target(ElementType.FIELD) -public @interface LightCycle { -} diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycleDispatcher.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycleDispatcher.java deleted file mode 100644 index 15d9841..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycleDispatcher.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.soundcloud.lightcycle; - -// TODO : rename ? -public interface LightCycleDispatcher { - - void bind(LightCycle lightCycle); - -} diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycles.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycles.java deleted file mode 100644 index e87afab..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/LightCycles.java +++ /dev/null @@ -1,257 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.util.Log; -import android.view.MenuItem; -import android.view.View; - -import java.lang.reflect.Method; - -public final class LightCycles { - private static final String TAG = LightCycles.class.getSimpleName(); - private static final String ANDROID_PREFIX = "android."; - private static final String JAVA_PREFIX = "java."; - - @SuppressWarnings("PMD.EmptyCatchBlock") - public static void bind(LightCycleDispatcher target) { - Method bindingMethod; - try { - bindingMethod = findBinderForClass(target.getClass()); - if (bindingMethod != null) { - bindingMethod.invoke(null, target); - } - } catch (Exception e) { - // no binder found, so ignore. - } - } - - private static String getInjectorClassName(String clsName) { - return clsName + "$LightCycleBinder"; - } - - private static Method findBinderForClass(Class cls) - throws IllegalAccessException, InstantiationException, NoSuchMethodException { - Method lightCycleInjectionMethod; - String clsName = cls.getName(); - if (clsName.startsWith(ANDROID_PREFIX) || clsName.startsWith(JAVA_PREFIX)) { - Log.d(TAG, "MISS: Reached framework class. Abandoning search."); - return null; - } - try { - Class binder = Class.forName(getInjectorClassName(clsName)); - lightCycleInjectionMethod = binder.getMethod("bind", cls); - Log.d(TAG, "HIT: Loaded LightCycle binder class."); - } catch (ClassNotFoundException e) { - Log.d(TAG, "Not found. Trying superclass " + cls.getSuperclass().getName()); - lightCycleInjectionMethod = findBinderForClass(cls.getSuperclass()); - } - return lightCycleInjectionMethod; - } - - public static ActivityLightCycle lift(final ActivityLightCycle lightCycle) { - return new ActivityLightCycle() { - - @Override - public void onCreate(Target activity, Bundle bundle) { - lightCycle.onCreate(activity, bundle); - } - - @Override - public void onNewIntent(Target activity, Intent intent) { - lightCycle.onNewIntent(activity, intent); - } - - @Override - public void onStart(Target activity) { - lightCycle.onStart(activity); - } - - @Override - public void onResume(Target activity) { - lightCycle.onResume(activity); - } - - @Override - public boolean onOptionsItemSelected(Target activity, MenuItem item) { - return lightCycle.onOptionsItemSelected(activity, item); - } - - @Override - public void onPause(Target activity) { - lightCycle.onPause(activity); - } - - @Override - public void onStop(Target activity) { - lightCycle.onStop(activity); - } - - @Override - public void onSaveInstanceState(Target activity, Bundle bundle) { - lightCycle.onSaveInstanceState(activity, bundle); - } - - @Override - public void onRestoreInstanceState(Target activity, Bundle bundle) { - lightCycle.onRestoreInstanceState(activity, bundle); - } - - @Override - public void onDestroy(Target activity) { - lightCycle.onDestroy(activity); - } - }; - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public static FragmentLightCycle lift(final FragmentLightCycle lightCycle) { - return new FragmentLightCycle() { - - @Override - public void onAttach(Target fragment, Activity activity) { - lightCycle.onAttach(fragment, activity); - } - - @Override - public void onAttach(Target fragment, Context context) { - lightCycle.onAttach(fragment, context); - } - - @Override - public void onCreate(Target fragment, Bundle bundle) { - lightCycle.onCreate(fragment, bundle); - } - - @Override - public void onViewCreated(Target fragment, View view, Bundle savedInstanceState) { - lightCycle.onViewCreated(fragment, view, savedInstanceState); - } - - @Override - public void onActivityCreated(Target fragment, Bundle bundle) { - lightCycle.onActivityCreated(fragment, bundle); - } - - @Override - public void onStart(Target fragment) { - lightCycle.onStart(fragment); - } - - @Override - public void onResume(Target fragment) { - lightCycle.onResume(fragment); - } - - @Override - public boolean onOptionsItemSelected(Target fragment, MenuItem item) { - return lightCycle.onOptionsItemSelected(fragment, item); - } - - @Override - public void onPause(Target fragment) { - lightCycle.onPause(fragment); - } - - @Override - public void onStop(Target fragment) { - lightCycle.onStop(fragment); - } - - @Override - public void onSaveInstanceState(Target fragment, Bundle bundle) { - lightCycle.onSaveInstanceState(fragment, bundle); - } - - @Override - public void onDestroyView(Target fragment) { - lightCycle.onDestroyView(fragment); - } - - @Override - public void onDestroy(Target fragment) { - lightCycle.onDestroy(fragment); - } - - @Override - public void onDetach(Target fragment) { - lightCycle.onDetach(fragment); - } - }; - } - - - public static SupportFragmentLightCycle lift(final SupportFragmentLightCycle lightCycle) { - return new SupportFragmentLightCycle() { - - @Override - public void onAttach(Target fragment, Activity activity) { - lightCycle.onAttach(fragment, activity); - } - - @Override - public void onCreate(Target fragment, Bundle bundle) { - lightCycle.onCreate(fragment, bundle); - } - - @Override - public void onViewCreated(Target fragment, View view, Bundle savedInstanceState) { - lightCycle.onViewCreated(fragment, view, savedInstanceState); - } - - @Override - public void onActivityCreated(Target fragment, Bundle bundle) { - lightCycle.onActivityCreated(fragment, bundle); - } - - @Override - public void onStart(Target fragment) { - lightCycle.onStart(fragment); - } - - @Override - public void onResume(Target fragment) { - lightCycle.onResume(fragment); - } - - @Override - public boolean onOptionsItemSelected(Target fragment, MenuItem item) { - return lightCycle.onOptionsItemSelected(fragment, item); - } - - @Override - public void onPause(Target fragment) { - lightCycle.onPause(fragment); - } - - @Override - public void onStop(Target fragment) { - lightCycle.onStop(fragment); - } - - @Override - public void onSaveInstanceState(Target fragment, Bundle bundle) { - lightCycle.onSaveInstanceState(fragment, bundle); - } - - @Override - public void onDestroyView(Target fragment) { - lightCycle.onDestroyView(fragment); - } - - @Override - public void onDestroy(Target fragment) { - lightCycle.onDestroy(fragment); - } - - @Override - public void onDetach(Target fragment) { - lightCycle.onDetach(fragment); - } - }; - } -} diff --git a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/SupportFragmentLightCycle.java b/lightcycle-api/src/main/java/com/soundcloud/lightcycle/SupportFragmentLightCycle.java deleted file mode 100644 index f2c578f..0000000 --- a/lightcycle-api/src/main/java/com/soundcloud/lightcycle/SupportFragmentLightCycle.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.MenuItem; -import android.view.View; - -public interface SupportFragmentLightCycle { - void onAttach(T fragment, Activity activity); - void onCreate(T fragment, Bundle bundle); - void onViewCreated(T fragment, View view, Bundle savedInstanceState); - void onActivityCreated(T fragment, Bundle bundle); - void onStart(T fragment); - void onResume(T fragment); - boolean onOptionsItemSelected(T fragment, MenuItem item); - void onPause(T fragment); - void onStop(T fragment); - void onSaveInstanceState(T fragment, Bundle bundle); - void onDestroyView(T fragment); - void onDestroy(T fragment); - void onDetach(T fragment); -} diff --git a/lightcycle-integration-test/.gitignore b/lightcycle-integration-test/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/lightcycle-integration-test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/lightcycle-integration-test/build.gradle b/lightcycle-integration-test/build.gradle deleted file mode 100644 index de86ac8..0000000 --- a/lightcycle-integration-test/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - - compileOptions { - sourceCompatibility rootProject.ext.sourceCompatibilityVersion - targetCompatibility rootProject.ext.targetCompatibilityVersion - } - - defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 - versionName "1.0" - } - -} - -dependencies { - annotationProcessor project(":lightcycle-processor") - - compile project(":lightcycle-lib") - compile deps.appcompat_v7 - - testCompile deps.roboelectric - testCompile deps.robolectric_support - testCompile deps.compiletesting -} diff --git a/lightcycle-integration-test/proguard-rules.pro b/lightcycle-integration-test/proguard-rules.pro deleted file mode 100644 index 6691aee..0000000 --- a/lightcycle-integration-test/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/yuwono-niko/Library/Android/sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/lightcycle-integration-test/src/main/AndroidManifest.xml b/lightcycle-integration-test/src/main/AndroidManifest.xml deleted file mode 100644 index 3b577f2..0000000 --- a/lightcycle-integration-test/src/main/AndroidManifest.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/ActivityLogger.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/ActivityLogger.java deleted file mode 100644 index e55237c..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/ActivityLogger.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.content.Intent; -import android.os.Bundle; -import android.view.MenuItem; - -import com.soundcloud.lightcycle.integration_test.callback.ActivityLifecycleCallback; - -public class ActivityLogger extends BaseActivityLogger { - - @Override - public void onCreate(SampleActivity activity, Bundle bundle) { - super.onCreate(activity, bundle); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onCreate, true); - } - - @Override - public void onStart(SampleActivity activity) { - super.onStart(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onStart, true); - } - - @Override - public void onRestoreInstanceState(SampleActivity activity, Bundle bundle) { - super.onRestoreInstanceState(activity, bundle); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onRestoreInstanceState, true); - } - - @Override - public void onResume(SampleActivity activity) { - super.onResume(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onResume, true); - } - - @Override - public void onPause(SampleActivity activity) { - super.onPause(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onPause, true); - } - - @Override - public void onSaveInstanceState(SampleActivity activity, Bundle bundle) { - super.onSaveInstanceState(activity, bundle); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onSaveInstanceState, true); - } - - @Override - public void onStop(SampleActivity activity) { - super.onStop(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onStop, true); - } - - @Override - public void onDestroy(SampleActivity activity) { - super.onDestroy(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onDestroy, true); - } - - @Override - public void onNewIntent(SampleActivity activity, Intent intent) { - super.onNewIntent(activity, intent); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onNewIntent, true); - } - - @Override - public boolean onOptionsItemSelected(SampleActivity activity, MenuItem item) { - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onOptionsItemSelected, true); - return super.onOptionsItemSelected(activity, item); - } - -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/AppCompatActivityLogger.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/AppCompatActivityLogger.java deleted file mode 100644 index 486a9e3..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/AppCompatActivityLogger.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.view.MenuItem; - -import com.soundcloud.lightcycle.integration_test.callback.ActivityLifecycleCallback; - -class AppCompatActivityLogger extends BaseActivityLogger { - - @Override - public void onCreate(AppCompatActivity activity, Bundle bundle) { - super.onCreate(activity, bundle); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onCreate, true); - } - - @Override - public void onStart(AppCompatActivity activity) { - super.onStart(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onStart, true); - } - - @Override - public void onRestoreInstanceState(AppCompatActivity activity, Bundle bundle) { - super.onRestoreInstanceState(activity, bundle); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onRestoreInstanceState, true); - } - - @Override - public void onResume(AppCompatActivity activity) { - super.onResume(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onResume, true); - } - - @Override - public void onPause(AppCompatActivity activity) { - super.onPause(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onPause, true); - } - - @Override - public void onSaveInstanceState(AppCompatActivity activity, Bundle bundle) { - super.onSaveInstanceState(activity, bundle); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onSaveInstanceState, true); - } - - @Override - public void onStop(AppCompatActivity activity) { - super.onStop(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onStop, true); - } - - @Override - public void onDestroy(AppCompatActivity activity) { - super.onDestroy(activity); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onDestroy, true); - } - - @Override - public void onNewIntent(AppCompatActivity activity, Intent intent) { - super.onNewIntent(activity, intent); - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onNewIntent, true); - } - - @Override - public boolean onOptionsItemSelected(AppCompatActivity activity, MenuItem item) { - lifecycleCallbackCallState.put(ActivityLifecycleCallback.onOptionsItemSelected, true); - return super.onOptionsItemSelected(activity, item); - } -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/BaseActivityLogger.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/BaseActivityLogger.java deleted file mode 100644 index 2542374..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/BaseActivityLogger.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.app.Activity; - -import com.soundcloud.lightcycle.DefaultActivityLightCycle; -import com.soundcloud.lightcycle.integration_test.callback.ActivityLifecycleCallback; - -import java.util.HashMap; -import java.util.Map; - -class BaseActivityLogger extends DefaultActivityLightCycle { - - Map lifecycleCallbackCallState; - - BaseActivityLogger() { - initializeLifecycleCallbackCallStateMap(); - } - - private void initializeLifecycleCallbackCallStateMap() { - this.lifecycleCallbackCallState = new HashMap<>(); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onCreate, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onStart, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onRestoreInstanceState, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onResume, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onPause, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onSaveInstanceState, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onStop, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onDestroy, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onNewIntent, false); - this.lifecycleCallbackCallState.put(ActivityLifecycleCallback.onOptionsItemSelected, false); - } - - boolean isActivityLifecycleCallbackCalled(ActivityLifecycleCallback callback) { - return lifecycleCallbackCallState.get(callback); - } -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/FragmentLogger.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/FragmentLogger.java deleted file mode 100644 index 9061534..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/FragmentLogger.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.View; - -import com.soundcloud.lightcycle.DefaultFragmentLightCycle; -import com.soundcloud.lightcycle.integration_test.callback.FragmentLifecycleCallback; - -import java.util.HashMap; -import java.util.Map; - -public class FragmentLogger extends DefaultFragmentLightCycle { - - private Map lifecycleCallbackCallState; - - FragmentLogger() { - initializeLifecycleCallbackCallStateMap(); - } - - @Override - public void onAttach(SampleFragment fragment, Activity activity) { - super.onAttach(fragment, activity); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onAttach, true); - } - - @Override - public void onAttach(SampleFragment fragment, Context context) { - super.onAttach(fragment, context); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onAttach, true); - } - - @Override - public void onCreate(SampleFragment fragment, Bundle bundle) { - super.onCreate(fragment, bundle); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onCreate, true); - } - - @Override - public void onViewCreated(SampleFragment fragment, View view, Bundle savedInstanceState) { - super.onViewCreated(fragment, view, savedInstanceState); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onViewCreated, true); - } - - @Override - public void onActivityCreated(SampleFragment fragment, Bundle bundle) { - super.onActivityCreated(fragment, bundle); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onActivityCreated, true); - } - - @Override - public void onStart(SampleFragment fragment) { - super.onStart(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onStart, true); - } - - @Override - public void onResume(SampleFragment fragment) { - super.onResume(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onResume, true); - } - - @Override - public void onPause(SampleFragment fragment) { - super.onPause(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onPause, true); - } - - @Override - public void onStop(SampleFragment fragment) { - super.onStop(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onStop, true); - } - - @Override - public void onSaveInstanceState(SampleFragment fragment, Bundle bundle) { - super.onSaveInstanceState(fragment, bundle); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onSaveInstanceState, true); - } - - @Override - public void onDestroyView(SampleFragment fragment) { - super.onDestroyView(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDestroyView, true); - } - - @Override - public void onDestroy(SampleFragment fragment) { - super.onDestroy(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDestroy, true); - } - - @Override - public void onDetach(SampleFragment fragment) { - super.onDetach(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDetach, true); - } - - boolean isFragmentLifecycleCallbackCalled(FragmentLifecycleCallback callback) { - return lifecycleCallbackCallState.get(callback); - } - - private void initializeLifecycleCallbackCallStateMap() { - this.lifecycleCallbackCallState = new HashMap<>(); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onAttach, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onCreate, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onViewCreated, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onActivityCreated, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onStart, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onResume, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onPause, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onStop, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onSaveInstanceState, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDestroyView, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDestroy, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDetach, false); - } -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleActivity.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleActivity.java deleted file mode 100644 index 0082ddc..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleActivity.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.view.Menu; - -import com.soundcloud.lightcycle.ActivityLightCycle; -import com.soundcloud.lightcycle.LightCycle; -import com.soundcloud.lightcycle.LightCycleActivity; -import com.soundcloud.lightcycle.LightCycleDispatcher; -import com.soundcloud.lightcycle.sample.basic.R; - -public class SampleActivity - extends LightCycleActivity - implements LightCycleDispatcher> { - - @LightCycle - ActivityLogger activityLogger = new ActivityLogger(); - - @Override - protected void setActivityContentView() { - setContentView(R.layout.activity_sample); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_search, menu); - return super.onCreateOptionsMenu(menu); - } -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleAppCompatActivity.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleAppCompatActivity.java deleted file mode 100644 index b224e2c..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleAppCompatActivity.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.view.Menu; - -import com.soundcloud.lightcycle.LightCycle; -import com.soundcloud.lightcycle.LightCycleAppCompatActivity; -import com.soundcloud.lightcycle.sample.basic.R; - -public class SampleAppCompatActivity extends LightCycleAppCompatActivity { - @LightCycle - AppCompatActivityLogger appCompatActivityLogger = new AppCompatActivityLogger(); - - @Override - protected void setActivityContentView() { - setContentView(R.layout.activity_sample); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_search, menu); - return super.onCreateOptionsMenu(menu); - } -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleFragment.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleFragment.java deleted file mode 100644 index 2c5f728..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleFragment.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.annotation.TargetApi; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.soundcloud.lightcycle.LightCycle; -import com.soundcloud.lightcycle.LightCycleFragment; -import com.soundcloud.lightcycle.sample.basic.R; - -@TargetApi(Build.VERSION_CODES.HONEYCOMB) -public class SampleFragment extends LightCycleFragment { - - @LightCycle - FragmentLogger fragmentLogger = new FragmentLogger(); - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_sample, container, false); - } -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleSupportFragment.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleSupportFragment.java deleted file mode 100644 index beb5735..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SampleSupportFragment.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.soundcloud.lightcycle.LightCycle; -import com.soundcloud.lightcycle.LightCycleSupportFragment; -import com.soundcloud.lightcycle.sample.basic.R; - -public class SampleSupportFragment extends LightCycleSupportFragment { - - @LightCycle - SupportFragmentLogger supportFragmentLogger = new SupportFragmentLogger(); - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_sample, container, false); - } -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SupportFragmentLogger.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SupportFragmentLogger.java deleted file mode 100644 index 1ab21a3..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/SupportFragmentLogger.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.app.Activity; -import android.os.Bundle; -import android.view.View; - -import com.soundcloud.lightcycle.DefaultSupportFragmentLightCycle; -import com.soundcloud.lightcycle.integration_test.callback.FragmentLifecycleCallback; - -import java.util.HashMap; -import java.util.Map; - -public class SupportFragmentLogger extends DefaultSupportFragmentLightCycle { - - private Map lifecycleCallbackCallState; - - SupportFragmentLogger() { - initializeLifecycleCallbackCallStateMap(); - } - - @Override - public void onAttach(SampleSupportFragment fragment, Activity activity) { - super.onAttach(fragment, activity); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onAttach, true); - } - - @Override - public void onCreate(SampleSupportFragment fragment, Bundle bundle) { - super.onCreate(fragment, bundle); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onCreate, true); - } - - @Override - public void onViewCreated(SampleSupportFragment fragment, View view, Bundle savedInstanceState) { - super.onViewCreated(fragment, view, savedInstanceState); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onViewCreated, true); - } - - @Override - public void onActivityCreated(SampleSupportFragment fragment, Bundle bundle) { - super.onActivityCreated(fragment, bundle); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onActivityCreated, true); - } - - @Override - public void onStart(SampleSupportFragment fragment) { - super.onStart(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onStart, true); - } - - @Override - public void onResume(SampleSupportFragment fragment) { - super.onResume(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onResume, true); - } - - @Override - public void onPause(SampleSupportFragment fragment) { - super.onPause(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onPause, true); - } - - @Override - public void onStop(SampleSupportFragment fragment) { - super.onStop(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onStop, true); - } - - @Override - public void onDestroyView(SampleSupportFragment fragment) { - super.onDestroyView(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDestroyView, true); - } - - @Override - public void onDestroy(SampleSupportFragment fragment) { - super.onDestroy(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDestroy, true); - } - - @Override - public void onDetach(SampleSupportFragment fragment) { - super.onDetach(fragment); - lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDetach, true); - } - - boolean isFragmentLifecycleCallbackCalled(FragmentLifecycleCallback callback) { - return lifecycleCallbackCallState.get(callback); - } - - private void initializeLifecycleCallbackCallStateMap() { - this.lifecycleCallbackCallState = new HashMap<>(); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onAttach, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onCreate, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onViewCreated, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onActivityCreated, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onStart, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onResume, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onPause, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onStop, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onSaveInstanceState, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDestroyView, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDestroy, false); - this.lifecycleCallbackCallState.put(FragmentLifecycleCallback.onDetach, false); - } -} diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/callback/ActivityLifecycleCallback.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/callback/ActivityLifecycleCallback.java deleted file mode 100644 index 2d86cdf..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/callback/ActivityLifecycleCallback.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.soundcloud.lightcycle.integration_test.callback; - -public enum ActivityLifecycleCallback { - onCreate, - onStart, - onResume, - onPause, - onStop, - onDestroy, - onSaveInstanceState, - onRestoreInstanceState, - onNewIntent, - onOptionsItemSelected -} \ No newline at end of file diff --git a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/callback/FragmentLifecycleCallback.java b/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/callback/FragmentLifecycleCallback.java deleted file mode 100644 index 9e7583e..0000000 --- a/lightcycle-integration-test/src/main/java/com/soundcloud/lightcycle/integration_test/callback/FragmentLifecycleCallback.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.soundcloud.lightcycle.integration_test.callback; - -public enum FragmentLifecycleCallback { - onAttach, - onCreate, - onViewCreated, - onActivityCreated, - onStart, - onResume, - onPause, - onStop, - onSaveInstanceState, - onDestroyView, - onDestroy, - onDetach -} diff --git a/lightcycle-integration-test/src/main/res/layout/activity_sample.xml b/lightcycle-integration-test/src/main/res/layout/activity_sample.xml deleted file mode 100644 index 9091838..0000000 --- a/lightcycle-integration-test/src/main/res/layout/activity_sample.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/lightcycle-integration-test/src/main/res/layout/fragment_sample.xml b/lightcycle-integration-test/src/main/res/layout/fragment_sample.xml deleted file mode 100644 index 9091838..0000000 --- a/lightcycle-integration-test/src/main/res/layout/fragment_sample.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/lightcycle-integration-test/src/main/res/menu/menu_search.xml b/lightcycle-integration-test/src/main/res/menu/menu_search.xml deleted file mode 100644 index 42d6ae3..0000000 --- a/lightcycle-integration-test/src/main/res/menu/menu_search.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/lightcycle-integration-test/src/main/res/values/colors.xml b/lightcycle-integration-test/src/main/res/values/colors.xml deleted file mode 100644 index 4cef1a9..0000000 --- a/lightcycle-integration-test/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - #ffffff - #bbbbbb - @color/soundcloud - #ff5500 - \ No newline at end of file diff --git a/lightcycle-integration-test/src/main/res/values/strings.xml b/lightcycle-integration-test/src/main/res/values/strings.xml deleted file mode 100644 index 5367825..0000000 --- a/lightcycle-integration-test/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - lightcycle-integration-test] - search - diff --git a/lightcycle-integration-test/src/main/res/values/styles.xml b/lightcycle-integration-test/src/main/res/values/styles.xml deleted file mode 100644 index 6e045f6..0000000 --- a/lightcycle-integration-test/src/main/res/values/styles.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/ActivityLoggerTest.java b/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/ActivityLoggerTest.java deleted file mode 100644 index 908ebe3..0000000 --- a/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/ActivityLoggerTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.content.Intent; -import android.os.Bundle; - -import com.google.common.truth.BooleanSubject; -import com.soundcloud.lightcycle.integration_test.callback.ActivityLifecycleCallback; -import com.soundcloud.lightcycle.sample.basic.BuildConfig; -import com.soundcloud.lightcycle.sample.basic.R; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.Shadows; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowActivity; -import org.robolectric.util.ActivityController; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static com.google.common.truth.Truth.assertThat; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 22) -public class ActivityLoggerTest { - private final ActivityController controller = Robolectric.buildActivity(SampleActivity.class); - private final SampleActivity sampleActivity = controller.get(); - private final ActivityLogger activityLogger = sampleActivity.activityLogger; - - @Test - public void onCreate() { - controller.create(); - assertLifecycleCallbackCallIsCorrect( - Collections.singletonList(ActivityLifecycleCallback.onCreate) - ); - } - - @Test - public void onStart() { - controller.create() - .start(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart) - ); - } - - @Test - public void onRestoreInstance() { - controller.create() - .start() - .restoreInstanceState(new Bundle()); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onRestoreInstanceState) - ); - } - - @Test - public void onResume() { - controller.create() - .start() - .resume(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onResume) - ); - } - - @Test - public void onPause() { - controller.create() - .start() - .resume() - .pause(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onResume, - ActivityLifecycleCallback.onPause) - ); - } - - @Test - public void onSaveInstanceState() { - controller.create() - .start() - .resume() - .pause() - .saveInstanceState(new Bundle()); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onResume, - ActivityLifecycleCallback.onPause, - ActivityLifecycleCallback.onSaveInstanceState) - ); - } - - @Test - public void onStop() { - controller.create() - .start() - .stop(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onStop) - ); - } - - @Test - public void onDestroy() { - controller.create() - .destroy(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onDestroy) - ); - } - - @Test - public void onNewIntent() { - controller.setup() - .newIntent(new Intent()); - assertThat(activityLogger.isActivityLifecycleCallbackCalled(ActivityLifecycleCallback.onNewIntent)).isTrue(); - } - - @Test - public void onOptionsItemSelected() { - controller.setup(); - ShadowActivity shadowActivity = Shadows.shadowOf(controller.get()); - shadowActivity.clickMenuItem(R.id.action_search); - assertThat(activityLogger.isActivityLifecycleCallbackCalled(ActivityLifecycleCallback.onOptionsItemSelected)).isTrue(); - } - - private void assertLifecycleCallbackCallIsCorrect(List callbacks) { - for (ActivityLifecycleCallback activityLifecycleCallback : ActivityLifecycleCallback.values()) { - BooleanSubject subject = assertThat(activityLogger.isActivityLifecycleCallbackCalled(activityLifecycleCallback)); - if (callbacks.contains(activityLifecycleCallback)) { - subject.isTrue(); - } else { - subject.isFalse(); - } - } - } -} \ No newline at end of file diff --git a/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/AppCompatActivityLoggerTest.java b/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/AppCompatActivityLoggerTest.java deleted file mode 100644 index 7420ca3..0000000 --- a/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/AppCompatActivityLoggerTest.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.content.Intent; -import android.os.Bundle; - -import com.google.common.truth.BooleanSubject; -import com.soundcloud.lightcycle.integration_test.callback.ActivityLifecycleCallback; -import com.soundcloud.lightcycle.sample.basic.BuildConfig; -import com.soundcloud.lightcycle.sample.basic.R; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.Shadows; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowActivity; -import org.robolectric.util.ActivityController; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static com.google.common.truth.Truth.assertThat; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 22) -public class AppCompatActivityLoggerTest { - private final ActivityController controller = Robolectric.buildActivity(SampleAppCompatActivity.class); - private final SampleAppCompatActivity sampleAppCompatActivity = controller.get(); - private final AppCompatActivityLogger appCompatActivityLogger = sampleAppCompatActivity.appCompatActivityLogger; - - @Test - public void onCreate() { - controller.create(); - assertLifecycleCallbackCallIsCorrect( - Collections.singletonList(ActivityLifecycleCallback.onCreate) - ); - } - - @Test - public void onStart() { - controller.create() - .start(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart) - ); - } - - @Test - public void onRestoreInstance() { - controller.create() - .start() - .restoreInstanceState(new Bundle()); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onRestoreInstanceState) - ); - } - - @Test - public void onResume() { - controller.create() - .start() - .resume(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onResume) - ); - } - - @Test - public void onPause() { - controller.create() - .start() - .resume() - .pause(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onResume, - ActivityLifecycleCallback.onPause) - ); - } - - @Test - public void onSaveInstanceState() { - controller.create() - .start() - .resume() - .pause() - .saveInstanceState(new Bundle()); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onResume, - ActivityLifecycleCallback.onPause, - ActivityLifecycleCallback.onSaveInstanceState) - ); - } - - @Test - public void onStop() { - controller.create() - .start() - .stop(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onStop) - ); - } - - @Test - public void onDestroy() { - controller.create() - .destroy(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onDestroy) - ); - } - - @Test - public void onNewIntent() { - controller.setup() - .newIntent(new Intent()); - - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onResume, - ActivityLifecycleCallback.onNewIntent) - ); - } - - @Test - public void onOptionsItemSelected() { - controller.setup(); - ShadowActivity shadowActivity = Shadows.shadowOf(controller.get()); - shadowActivity.clickMenuItem(R.id.action_search); - - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(ActivityLifecycleCallback.onCreate, - ActivityLifecycleCallback.onStart, - ActivityLifecycleCallback.onResume, - ActivityLifecycleCallback.onOptionsItemSelected) - ); - } - - private void assertLifecycleCallbackCallIsCorrect(List callbacks) { - for (ActivityLifecycleCallback activityLifecycleCallback : ActivityLifecycleCallback.values()) { - BooleanSubject subject = assertThat(appCompatActivityLogger.isActivityLifecycleCallbackCalled(activityLifecycleCallback)); - if (callbacks.contains(activityLifecycleCallback)) { - subject.isTrue(); - } else { - subject.isFalse(); - } - } - } -} diff --git a/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/FragmentLoggerTest.java b/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/FragmentLoggerTest.java deleted file mode 100644 index 10c8049..0000000 --- a/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/FragmentLoggerTest.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import android.os.Bundle; - -import com.google.common.truth.BooleanSubject; -import com.soundcloud.lightcycle.integration_test.callback.FragmentLifecycleCallback; -import com.soundcloud.lightcycle.sample.basic.BuildConfig; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.util.FragmentController; - -import java.util.Arrays; -import java.util.List; - -import static com.google.common.truth.Truth.assertThat; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 22) -public class FragmentLoggerTest { - private final SampleFragment sampleFragment = new SampleFragment(); - private final FragmentLogger fragmentLogger = sampleFragment.fragmentLogger; - private final FragmentController controller = FragmentController.of(sampleFragment); - - @Test - public void onCreate() { - controller.create(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated) - ); - } - - @Test - public void onStart() { - controller.create() - .start(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onStart) - ); - } - - @Test - public void onResume() { - controller.create() - .start() - .resume(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onStart, - FragmentLifecycleCallback.onResume) - ); - } - - @Test - public void onPause() { - controller.create() - .start() - .resume() - .pause(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onStart, - FragmentLifecycleCallback.onResume, - FragmentLifecycleCallback.onPause) - ); - } - - @Test - public void onSaveInstanceState() { - controller.create() - .start() - .resume() - .pause() - .saveInstanceState(new Bundle()); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onStart, - FragmentLifecycleCallback.onResume, - FragmentLifecycleCallback.onPause, - FragmentLifecycleCallback.onSaveInstanceState) - ); - } - - @Test - public void onStop() { - controller.create() - .start() - .stop(); - - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onStart, - FragmentLifecycleCallback.onStop) - ); - } - - @Test - public void onDestroy() { - controller.create() - .destroy(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onDestroyView, - FragmentLifecycleCallback.onDestroy, - FragmentLifecycleCallback.onDetach) - ); - } - - private void assertLifecycleCallbackCallIsCorrect(List callbacks) { - for (FragmentLifecycleCallback fragmentLifecycleCallback : FragmentLifecycleCallback.values()) { - BooleanSubject subject = assertThat(fragmentLogger.isFragmentLifecycleCallbackCalled(fragmentLifecycleCallback)); - if (callbacks.contains(fragmentLifecycleCallback)) { - subject.isTrue(); - } else { - subject.isFalse(); - } - } - } -} \ No newline at end of file diff --git a/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/SupportFragmentLoggerTest.java b/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/SupportFragmentLoggerTest.java deleted file mode 100644 index b23582b..0000000 --- a/lightcycle-integration-test/src/test/java/com/soundcloud/lightcycle/integration_test/SupportFragmentLoggerTest.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.soundcloud.lightcycle.integration_test; - -import com.google.common.truth.BooleanSubject; -import com.soundcloud.lightcycle.integration_test.callback.FragmentLifecycleCallback; -import com.soundcloud.lightcycle.sample.basic.BuildConfig; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.support.v4.SupportFragmentController; - -import java.util.Arrays; -import java.util.List; - -import static com.google.common.truth.Truth.assertThat; - -@RunWith(RobolectricTestRunner.class) -@Config(constants = BuildConfig.class, sdk = 22) -public class SupportFragmentLoggerTest { - private final SampleSupportFragment sampleSupportFragment = new SampleSupportFragment(); - private final SupportFragmentLogger supportFragmentLogger = sampleSupportFragment.supportFragmentLogger; - private final SupportFragmentController controller = SupportFragmentController.of(sampleSupportFragment); - - @Test - public void onCreate() { - controller.create(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate) - ); - } - - @Test - public void onStart() { - controller.create() - .start(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onStart, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated) - ); - } - - @Test - public void onResume() { - controller.create() - .start() - .resume(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onStart, - FragmentLifecycleCallback.onResume) - ); - } - - @Test - public void onPause() { - controller.create() - .start() - .resume() - .pause(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onStart, - FragmentLifecycleCallback.onResume, - FragmentLifecycleCallback.onPause) - ); - } - - @Test - public void onStop() { - controller.create() - .start() - .stop(); - - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onStart, - FragmentLifecycleCallback.onStop) - ); - } - - @Test - public void onDestroy() { - controller.create() - .destroy(); - assertLifecycleCallbackCallIsCorrect( - Arrays.asList(FragmentLifecycleCallback.onAttach, - FragmentLifecycleCallback.onCreate, - FragmentLifecycleCallback.onViewCreated, - FragmentLifecycleCallback.onActivityCreated, - FragmentLifecycleCallback.onDestroyView, - FragmentLifecycleCallback.onDestroy, - FragmentLifecycleCallback.onDetach) - ); - } - - private void assertLifecycleCallbackCallIsCorrect(List callbacks) { - for (FragmentLifecycleCallback fragmentLifecycleCallback : FragmentLifecycleCallback.values()) { - BooleanSubject subject = assertThat(supportFragmentLogger.isFragmentLifecycleCallbackCalled(fragmentLifecycleCallback)); - if (callbacks.contains(fragmentLifecycleCallback)) { - subject.isTrue(); - } else { - subject.isFalse(); - } - } - } - -} \ No newline at end of file diff --git a/lightcycle-lib/.gitignore b/lightcycle-lib/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/lightcycle-lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/lightcycle-lib/build.gradle b/lightcycle-lib/build.gradle deleted file mode 100644 index b293179..0000000 --- a/lightcycle-lib/build.gradle +++ /dev/null @@ -1,52 +0,0 @@ -apply plugin: 'com.android.library' -apply plugin: 'checkstyle' -apply from: rootProject.file('gradle/gradle-mvn-push.gradle') - -android { - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - - defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - - versionCode 1 - versionName "1.0" - } - - buildTypes { - release { - consumerProguardFiles 'proguard-rules.txt' - } - } - - compileOptions { - sourceCompatibility rootProject.ext.sourceCompatibilityVersion - targetCompatibility rootProject.ext.targetCompatibilityVersion - } - - lintOptions { - textReport true - textOutput "stdout" - } - - testOptions { - unitTests.returnDefaultValues = true - } -} - -checkstyle { - configFile rootProject.file('checkstyle.xml') - showViolations true -} - -dependencies { - compile project(':lightcycle-api') - provided deps.support_v4 - compile deps.appcompat_v7 - compile deps.preference_v7 - compile deps.support_annotations - - testCompile deps.mockito - testCompile deps.junit -} diff --git a/lightcycle-lib/gradle.properties b/lightcycle-lib/gradle.properties deleted file mode 100644 index ecc16b7..0000000 --- a/lightcycle-lib/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -POM_NAME=LightCycle library -POM_ARTIFACT_ID=lightcycle-lib -POM_PACKAGING=aar \ No newline at end of file diff --git a/lightcycle-lib/proguard-rules.txt b/lightcycle-lib/proguard-rules.txt deleted file mode 100644 index 33a514a..0000000 --- a/lightcycle-lib/proguard-rules.txt +++ /dev/null @@ -1,6 +0,0 @@ --keep class com.soundcloud.** { *; } - --keep class com.soundcloud.lightcycle.** { *; } --dontwarn com.soundcloud.lightcycle.** --keep class **$LightCycleBinder { *; } - diff --git a/lightcycle-lib/src/main/AndroidManifest.xml b/lightcycle-lib/src/main/AndroidManifest.xml deleted file mode 100644 index 5e22c46..0000000 --- a/lightcycle-lib/src/main/AndroidManifest.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/ActivityLightCycleDispatcher.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/ActivityLightCycleDispatcher.java deleted file mode 100644 index 77e80b3..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/ActivityLightCycleDispatcher.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.soundcloud.lightcycle.util.Preconditions; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.view.MenuItem; - -import java.util.HashSet; -import java.util.Set; - -public class ActivityLightCycleDispatcher - implements LightCycleDispatcher>, ActivityLightCycle { - private final Set> activityLightCycles; - - public ActivityLightCycleDispatcher() { - this.activityLightCycles = new HashSet<>(); - } - - - @Override - public void bind(ActivityLightCycle lightCycle) { - Preconditions.checkBindingTarget(lightCycle); - this.activityLightCycles.add(lightCycle); - } - - @Override - public void onCreate(T activity, @Nullable Bundle bundle) { - LightCycles.bind(this); - for (ActivityLightCycle component : activityLightCycles) { - component.onCreate(activity, bundle); - } - } - - @Override - public void onNewIntent(T activity, Intent intent) { - for (ActivityLightCycle component : activityLightCycles) { - component.onNewIntent(activity, intent); - } - } - - @Override - public void onStart(T activity) { - for (ActivityLightCycle component : activityLightCycles) { - component.onStart(activity); - } - } - - @Override - public void onResume(T activity) { - for (ActivityLightCycle component : activityLightCycles) { - component.onResume(activity); - } - } - - @Override - public boolean onOptionsItemSelected(T activity, MenuItem item) { - for (ActivityLightCycle component : activityLightCycles) { - if (component.onOptionsItemSelected(activity, item)) { - return true; - } - } - return false; - } - - @Override - public void onPause(T activity) { - for (ActivityLightCycle component : activityLightCycles) { - component.onPause(activity); - } - } - - @Override - public void onStop(T activity) { - for (ActivityLightCycle component : activityLightCycles) { - component.onStop(activity); - } - } - - @Override - public void onSaveInstanceState(T activity, Bundle bundle) { - for (ActivityLightCycle component : activityLightCycles) { - component.onSaveInstanceState(activity, bundle); - } - } - - @Override - public void onRestoreInstanceState(T activity, Bundle bundle) { - for (ActivityLightCycle component : activityLightCycles) { - component.onRestoreInstanceState(activity, bundle); - } - } - - @Override - public void onDestroy(T activity) { - for (ActivityLightCycle component : activityLightCycles) { - component.onDestroy(activity); - } - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/FragmentLightCycleDispatcher.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/FragmentLightCycleDispatcher.java deleted file mode 100644 index 2dd8327..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/FragmentLightCycleDispatcher.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.soundcloud.lightcycle.util.Preconditions; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.Fragment; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.view.MenuItem; -import android.view.View; - -import java.util.HashSet; -import java.util.Set; - -@TargetApi(Build.VERSION_CODES.HONEYCOMB) -public class FragmentLightCycleDispatcher - implements LightCycleDispatcher>, FragmentLightCycle { - private final Set> fragmentLightCycles; - - public FragmentLightCycleDispatcher() { - this.fragmentLightCycles = new HashSet<>(); - } - - @Override - public void bind(FragmentLightCycle lightCycle) { - Preconditions.checkBindingTarget(lightCycle); - fragmentLightCycles.add(lightCycle); - } - - @Override - public void onAttach(T fragment, Activity activity) { - LightCycles.bind(this); - for (FragmentLightCycle component : fragmentLightCycles) { - component.onAttach(fragment, activity); - } - } - - @Override - public void onAttach(T fragment, Context context) { - LightCycles.bind(this); - for (FragmentLightCycle component : fragmentLightCycles) { - component.onAttach(fragment, context); - } - } - - @Override - public void onCreate(T fragment, @Nullable Bundle bundle) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onCreate(fragment, bundle); - } - } - - @Override - public void onViewCreated(T fragment, View view, @Nullable Bundle savedInstanceState) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onViewCreated(fragment, view, savedInstanceState); - } - } - - @Override - public void onActivityCreated(T fragment, Bundle bundle) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onActivityCreated(fragment, bundle); - } - } - - @Override - public void onStart(T fragment) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onStart(fragment); - } - } - - @Override - public void onResume(T fragment) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onResume(fragment); - } - } - - @Override - public boolean onOptionsItemSelected(T fragment, MenuItem item) { - for (FragmentLightCycle component : fragmentLightCycles) { - if (component.onOptionsItemSelected(fragment, item)) { - return true; - } - } - return false; - } - - @Override - public void onPause(T fragment) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onPause(fragment); - } - } - - @Override - public void onStop(T fragment) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onStop(fragment); - } - } - - @Override - public void onSaveInstanceState(T fragment, Bundle bundle) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onSaveInstanceState(fragment, bundle); - } - } - - @Override - public void onDestroyView(T fragment) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onDestroyView(fragment); - } - } - - @Override - public void onDestroy(T fragment) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onDestroy(fragment); - } - } - - @Override - public void onDetach(T fragment) { - for (FragmentLightCycle component : fragmentLightCycles) { - component.onDetach(fragment); - } - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleActionBarActivity.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleActionBarActivity.java deleted file mode 100644 index b216bd8..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleActionBarActivity.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; -import android.view.MenuItem; - -import com.soundcloud.lightcycle.util.Preconditions; - -@Deprecated -public abstract class LightCycleActionBarActivity - extends ActionBarActivity - implements LightCycleDispatcher> { - - private final ActivityLightCycleDispatcher lightCycleDispatcher; - - public LightCycleActionBarActivity() { - lightCycleDispatcher = new ActivityLightCycleDispatcher<>(); - } - - @Override - public void bind(ActivityLightCycle lightCycle) { - Preconditions.checkBindingTarget(lightCycle); - lightCycleDispatcher.bind(lightCycle); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setActivityContentView(); - LightCycles.bind(this); - lightCycleDispatcher.onCreate(activity(), savedInstanceState); - } - - protected abstract void setActivityContentView(); - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - lightCycleDispatcher.onNewIntent(activity(), intent); - } - - @Override - protected void onStart() { - super.onStart(); - lightCycleDispatcher.onStart(activity()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return lightCycleDispatcher.onOptionsItemSelected(activity(), item); - } - - @Override - protected void onStop() { - lightCycleDispatcher.onStop(activity()); - super.onStop(); - } - - @Override - protected void onResume() { - super.onResume(); - lightCycleDispatcher.onResume(activity()); - } - - @Override - protected void onPause() { - lightCycleDispatcher.onPause(activity()); - super.onPause(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - lightCycleDispatcher.onSaveInstanceState(activity(), outState); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - lightCycleDispatcher.onRestoreInstanceState(activity(), savedInstanceState); - } - - @Override - protected void onDestroy() { - lightCycleDispatcher.onDestroy(activity()); - super.onDestroy(); - } - - @SuppressWarnings("unchecked") - private ActivityType activity() { - return (ActivityType) this; - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleActivity.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleActivity.java deleted file mode 100644 index ff9bbfa..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleActivity.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.MenuItem; - -import com.soundcloud.lightcycle.util.Preconditions; - -public abstract class LightCycleActivity - extends Activity - implements LightCycleDispatcher> { - - private final ActivityLightCycleDispatcher lightCycleDispatcher; - - public LightCycleActivity() { - lightCycleDispatcher = new ActivityLightCycleDispatcher<>(); - } - - @Override - public void bind(ActivityLightCycle lightCycle) { - Preconditions.checkBindingTarget(lightCycle); - lightCycleDispatcher.bind(lightCycle); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setActivityContentView(); - LightCycles.bind(this); - lightCycleDispatcher.onCreate(activity(), savedInstanceState); - } - - protected abstract void setActivityContentView(); - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - lightCycleDispatcher.onNewIntent(activity(), intent); - } - - @Override - protected void onStart() { - super.onStart(); - lightCycleDispatcher.onStart(activity()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return lightCycleDispatcher.onOptionsItemSelected(activity(), item); - } - - @Override - protected void onStop() { - lightCycleDispatcher.onStop(activity()); - super.onStop(); - } - - @Override - protected void onResume() { - super.onResume(); - lightCycleDispatcher.onResume(activity()); - } - - @Override - protected void onPause() { - lightCycleDispatcher.onPause(activity()); - super.onPause(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - lightCycleDispatcher.onSaveInstanceState(activity(), outState); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - lightCycleDispatcher.onRestoreInstanceState(activity(), savedInstanceState); - } - - @Override - protected void onDestroy() { - lightCycleDispatcher.onDestroy(activity()); - super.onDestroy(); - } - - @SuppressWarnings("unchecked") - private ActivityType activity() { - return (ActivityType) this; - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleAppCompatActivity.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleAppCompatActivity.java deleted file mode 100644 index 976cb51..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleAppCompatActivity.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.view.MenuItem; - -import com.soundcloud.lightcycle.util.Preconditions; - -public abstract class LightCycleAppCompatActivity - extends AppCompatActivity - implements LightCycleDispatcher> { - - private final ActivityLightCycleDispatcher lightCycleDispatcher; - - public LightCycleAppCompatActivity() { - lightCycleDispatcher = new ActivityLightCycleDispatcher<>(); - } - - @Override - public void bind(ActivityLightCycle lightCycle) { - Preconditions.checkBindingTarget(lightCycle); - lightCycleDispatcher.bind(lightCycle); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setActivityContentView(); - LightCycles.bind(this); - lightCycleDispatcher.onCreate(activity(), savedInstanceState); - } - - protected abstract void setActivityContentView(); - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - lightCycleDispatcher.onNewIntent(activity(), intent); - } - - @Override - protected void onStart() { - super.onStart(); - lightCycleDispatcher.onStart(activity()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return lightCycleDispatcher.onOptionsItemSelected(activity(), item); - } - - @Override - protected void onStop() { - lightCycleDispatcher.onStop(activity()); - super.onStop(); - } - - @Override - protected void onResume() { - super.onResume(); - lightCycleDispatcher.onResume(activity()); - } - - @Override - protected void onPause() { - lightCycleDispatcher.onPause(activity()); - super.onPause(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - lightCycleDispatcher.onSaveInstanceState(activity(), outState); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - lightCycleDispatcher.onRestoreInstanceState(activity(), savedInstanceState); - } - - @Override - protected void onDestroy() { - lightCycleDispatcher.onDestroy(activity()); - super.onDestroy(); - } - - @SuppressWarnings("unchecked") - private ActivityType activity() { - return (ActivityType) this; - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleFragment.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleFragment.java deleted file mode 100644 index 0120d00..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleFragment.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.Fragment; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; - -import com.soundcloud.lightcycle.util.Preconditions; - -@TargetApi(Build.VERSION_CODES.HONEYCOMB) -public abstract class LightCycleFragment extends Fragment implements LightCycleDispatcher> { - - private final FragmentLightCycleDispatcher lifeCycleDispatcher; - private boolean bound; - - public LightCycleFragment() { - lifeCycleDispatcher = new FragmentLightCycleDispatcher<>(); - } - - @Override - public void bind(FragmentLightCycle lifeCycleComponent) { - Preconditions.checkBindingTarget(lifeCycleComponent); - lifeCycleDispatcher.bind(lifeCycleComponent); - } - - @Override - @TargetApi(23) - public void onAttach(Context context) { - super.onAttach(context); - bindIfNecessary(); - lifeCycleDispatcher.onAttach(fragment(), context); - } - - /* - * Deprecated on API 23 - * Use onAttach(Context) instead - */ - @Override - @SuppressWarnings("deprecation") - public void onAttach(Activity activity) { - super.onAttach(activity); - bindIfNecessary(); - lifeCycleDispatcher.onAttach(fragment(), activity); - } - - private void bindIfNecessary() { - if (!bound) { - LightCycles.bind(this); - bound = true; - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - lifeCycleDispatcher.onCreate(fragment(), savedInstanceState); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - lifeCycleDispatcher.onViewCreated(fragment(), view, savedInstanceState); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - lifeCycleDispatcher.onActivityCreated(fragment(), savedInstanceState); - } - - @Override - public void onStart() { - super.onStart(); - lifeCycleDispatcher.onStart(fragment()); - } - - @Override - public void onResume() { - super.onResume(); - lifeCycleDispatcher.onResume(fragment()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return lifeCycleDispatcher.onOptionsItemSelected(fragment(), item); - } - - @Override - public void onPause() { - lifeCycleDispatcher.onPause(fragment()); - super.onPause(); - } - - @Override - public void onStop() { - lifeCycleDispatcher.onStop(fragment()); - super.onStop(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - lifeCycleDispatcher.onSaveInstanceState(fragment(), outState); - super.onSaveInstanceState(outState); - } - - @Override - public void onDestroyView() { - lifeCycleDispatcher.onDestroyView(fragment()); - super.onDestroyView(); - } - - @Override - public void onDestroy() { - lifeCycleDispatcher.onDestroy(fragment()); - super.onDestroy(); - } - - @Override - public void onDetach() { - lifeCycleDispatcher.onDetach(fragment()); - super.onDetach(); - } - - @SuppressWarnings("unchecked") - private FragmentType fragment() { - return (FragmentType) this; - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCyclePreferenceFragmentCompat.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCyclePreferenceFragmentCompat.java deleted file mode 100644 index 88e7c01..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCyclePreferenceFragmentCompat.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v7.preference.PreferenceFragmentCompat; -import android.view.MenuItem; -import android.view.View; - -import com.soundcloud.lightcycle.util.Preconditions; - -public abstract class LightCyclePreferenceFragmentCompat - extends PreferenceFragmentCompat implements LightCycleDispatcher> { - - private final SupportFragmentLightCycleDispatcher lifeCycleDispatcher; - private boolean bound; - - public LightCyclePreferenceFragmentCompat() { - lifeCycleDispatcher = new SupportFragmentLightCycleDispatcher<>(); - } - - @Override - public void bind(SupportFragmentLightCycle lifeCycleComponent) { - Preconditions.checkBindingTarget(lifeCycleComponent); - lifeCycleDispatcher.bind(lifeCycleComponent); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - bindIfNecessary(); - lifeCycleDispatcher.onAttach(fragment(), activity); - } - - private void bindIfNecessary() { - if (!bound) { - LightCycles.bind(this); - bound = true; - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - lifeCycleDispatcher.onCreate(fragment(), savedInstanceState); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - lifeCycleDispatcher.onViewCreated(fragment(), view, savedInstanceState); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - lifeCycleDispatcher.onActivityCreated(fragment(), savedInstanceState); - } - - @Override - public void onStart() { - super.onStart(); - lifeCycleDispatcher.onStart(fragment()); - } - - @Override - public void onResume() { - super.onResume(); - lifeCycleDispatcher.onResume(fragment()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return lifeCycleDispatcher.onOptionsItemSelected(fragment(), item); - } - - @Override - public void onPause() { - lifeCycleDispatcher.onPause(fragment()); - super.onPause(); - } - - @Override - public void onStop() { - lifeCycleDispatcher.onStop(fragment()); - super.onStop(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - lifeCycleDispatcher.onSaveInstanceState(fragment(), outState); - super.onSaveInstanceState(outState); - } - - @Override - public void onDestroyView() { - lifeCycleDispatcher.onDestroyView(fragment()); - super.onDestroyView(); - } - - @Override - public void onDestroy() { - lifeCycleDispatcher.onDestroy(fragment()); - super.onDestroy(); - } - - @Override - public void onDetach() { - lifeCycleDispatcher.onDetach(fragment()); - super.onDetach(); - } - - @SuppressWarnings("unchecked") - private FragmentType fragment() { - return (FragmentType) this; - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleSupportDialogFragment.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleSupportDialogFragment.java deleted file mode 100644 index c5ef2b8..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleSupportDialogFragment.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.Fragment; -import android.view.MenuItem; -import android.view.View; - -import com.soundcloud.lightcycle.util.Preconditions; - -public abstract class LightCycleSupportDialogFragment - extends DialogFragment implements LightCycleDispatcher> { - - private final SupportFragmentLightCycleDispatcher lifeCycleDispatcher; - private boolean bound; - - public LightCycleSupportDialogFragment() { - lifeCycleDispatcher = new SupportFragmentLightCycleDispatcher<>(); - } - - @Override - public void bind(SupportFragmentLightCycle lifeCycleComponent) { - Preconditions.checkBindingTarget(lifeCycleComponent); - lifeCycleDispatcher.bind(lifeCycleComponent); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - bindIfNecessary(); - lifeCycleDispatcher.onAttach(fragment(), activity); - } - - private void bindIfNecessary() { - if (!bound) { - LightCycles.bind(this); - bound = true; - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - lifeCycleDispatcher.onCreate(fragment(), savedInstanceState); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - lifeCycleDispatcher.onViewCreated(fragment(), view, savedInstanceState); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - lifeCycleDispatcher.onActivityCreated(fragment(), savedInstanceState); - } - - @Override - public void onStart() { - super.onStart(); - lifeCycleDispatcher.onStart(fragment()); - } - - @Override - public void onResume() { - super.onResume(); - lifeCycleDispatcher.onResume(fragment()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return lifeCycleDispatcher.onOptionsItemSelected(fragment(), item); - } - - @Override - public void onPause() { - lifeCycleDispatcher.onPause(fragment()); - super.onPause(); - } - - @Override - public void onStop() { - lifeCycleDispatcher.onStop(fragment()); - super.onStop(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - lifeCycleDispatcher.onSaveInstanceState(fragment(), outState); - super.onSaveInstanceState(outState); - } - - @Override - public void onDestroyView() { - lifeCycleDispatcher.onDestroyView(fragment()); - super.onDestroyView(); - } - - @Override - public void onDestroy() { - lifeCycleDispatcher.onDestroy(fragment()); - super.onDestroy(); - } - - @Override - public void onDetach() { - lifeCycleDispatcher.onDetach(fragment()); - super.onDetach(); - } - - @SuppressWarnings("unchecked") - private FragmentType fragment() { - return (FragmentType) this; - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleSupportFragment.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleSupportFragment.java deleted file mode 100644 index d4acd40..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/LightCycleSupportFragment.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.soundcloud.lightcycle; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.MenuItem; -import android.view.View; - -import com.soundcloud.lightcycle.util.Preconditions; - -public abstract class LightCycleSupportFragment extends Fragment implements LightCycleDispatcher> { - - private final SupportFragmentLightCycleDispatcher lifeCycleDispatcher; - private boolean bound; - - public LightCycleSupportFragment() { - lifeCycleDispatcher = new SupportFragmentLightCycleDispatcher<>(); - } - - @Override - public void bind(SupportFragmentLightCycle lifeCycleComponent) { - Preconditions.checkBindingTarget(lifeCycleComponent); - lifeCycleDispatcher.bind(lifeCycleComponent); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - bindIfNecessary(); - lifeCycleDispatcher.onAttach(fragment(), activity); - } - - private void bindIfNecessary() { - if (!bound) { - LightCycles.bind(this); - bound = true; - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - lifeCycleDispatcher.onCreate(fragment(), savedInstanceState); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - lifeCycleDispatcher.onViewCreated(fragment(), view, savedInstanceState); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - lifeCycleDispatcher.onActivityCreated(fragment(), savedInstanceState); - } - - @Override - public void onStart() { - super.onStart(); - lifeCycleDispatcher.onStart(fragment()); - } - - @Override - public void onResume() { - super.onResume(); - lifeCycleDispatcher.onResume(fragment()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return lifeCycleDispatcher.onOptionsItemSelected(fragment(), item); - } - - @Override - public void onPause() { - lifeCycleDispatcher.onPause(fragment()); - super.onPause(); - } - - @Override - public void onStop() { - lifeCycleDispatcher.onStop(fragment()); - super.onStop(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - lifeCycleDispatcher.onSaveInstanceState(fragment(), outState); - super.onSaveInstanceState(outState); - } - - @Override - public void onDestroyView() { - lifeCycleDispatcher.onDestroyView(fragment()); - super.onDestroyView(); - } - - @Override - public void onDestroy() { - lifeCycleDispatcher.onDestroy(fragment()); - super.onDestroy(); - } - - @Override - public void onDetach() { - lifeCycleDispatcher.onDetach(fragment()); - super.onDetach(); - } - - @SuppressWarnings("unchecked") - private FragmentType fragment() { - return (FragmentType) this; - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/SupportFragmentLightCycleDispatcher.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/SupportFragmentLightCycleDispatcher.java deleted file mode 100644 index 815a604..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/SupportFragmentLightCycleDispatcher.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.soundcloud.lightcycle.util.Preconditions; - -import android.app.Activity; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; -import android.view.MenuItem; -import android.view.View; - -import java.util.HashSet; -import java.util.Set; - -public class SupportFragmentLightCycleDispatcher - implements LightCycleDispatcher>, SupportFragmentLightCycle { - private final Set> fragmentLightCycles; - - public SupportFragmentLightCycleDispatcher() { - this.fragmentLightCycles = new HashSet<>(); - } - - @Override - public void bind(SupportFragmentLightCycle lightCycle) { - Preconditions.checkBindingTarget(lightCycle); - fragmentLightCycles.add(lightCycle); - } - - @Override - public void onAttach(T fragment, Activity activity) { - LightCycles.bind(this); - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onAttach(fragment, activity); - } - } - - @Override - public void onCreate(T fragment, @Nullable Bundle bundle) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onCreate(fragment, bundle); - } - } - - @Override - public void onViewCreated(T fragment, View view, @Nullable Bundle savedInstanceState) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onViewCreated(fragment, view, savedInstanceState); - } - } - - @Override - public void onActivityCreated(T fragment, Bundle bundle) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onActivityCreated(fragment, bundle); - } - } - - @Override - public void onStart(T fragment) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onStart(fragment); - } - } - - @Override - public void onResume(T fragment) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onResume(fragment); - } - } - - @Override - public boolean onOptionsItemSelected(T fragment, MenuItem item) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - if (component.onOptionsItemSelected(fragment, item)) { - return true; - } - } - return false; - } - - @Override - public void onPause(T fragment) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onPause(fragment); - } - } - - @Override - public void onStop(T fragment) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onStop(fragment); - } - } - - @Override - public void onSaveInstanceState(T fragment, Bundle bundle) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onSaveInstanceState(fragment, bundle); - } - } - - @Override - public void onDestroyView(T fragment) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onDestroyView(fragment); - } - } - - @Override - public void onDestroy(T fragment) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onDestroy(fragment); - } - } - - @Override - public void onDetach(T fragment) { - for (SupportFragmentLightCycle component : fragmentLightCycles) { - component.onDetach(fragment); - } - } -} diff --git a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/util/Preconditions.java b/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/util/Preconditions.java deleted file mode 100644 index 4244095..0000000 --- a/lightcycle-lib/src/main/java/com/soundcloud/lightcycle/util/Preconditions.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.soundcloud.lightcycle.util; - -import com.soundcloud.lightcycle.ActivityLightCycle; -import com.soundcloud.lightcycle.FragmentLightCycle; -import com.soundcloud.lightcycle.SupportFragmentLightCycle; - -public final class Preconditions { - - private static final String BINDING_TARGET_NULL_ERROR_MESSAGE = "Binding target must not be null"; - - public static void checkBindingTarget(final ActivityLightCycle activityLightCycle) { - if (activityLightCycle == null) { - throw new NullPointerException(BINDING_TARGET_NULL_ERROR_MESSAGE); - } - } - - public static void checkBindingTarget(final FragmentLightCycle fragmentLightCycle) { - if (fragmentLightCycle == null) { - throw new NullPointerException(BINDING_TARGET_NULL_ERROR_MESSAGE); - } - } - - public static void checkBindingTarget(final SupportFragmentLightCycle supportFragmentLightCycle) { - if (supportFragmentLightCycle == null) { - throw new NullPointerException(BINDING_TARGET_NULL_ERROR_MESSAGE); - } - } -} diff --git a/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/ActivityLightCycleDispatcherTest.java b/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/ActivityLightCycleDispatcherTest.java deleted file mode 100644 index 618f2de..0000000 --- a/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/ActivityLightCycleDispatcherTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.soundcloud.lightcycle; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.support.v4.app.FragmentActivity; - -@RunWith(MockitoJUnitRunner.class) -public class ActivityLightCycleDispatcherTest { - @Mock private ActivityLightCycle lightCycleComponent1; - @Mock private ActivityLightCycle lightCycleComponent2; - @Mock private FragmentActivity activity; - private ActivityLightCycleDispatcher dispatcher; - - @Before - public void setUp() throws Exception { - dispatcher = new ActivityLightCycleDispatcher<>(); - dispatcher.bind(lightCycleComponent1); - dispatcher.bind(lightCycleComponent2); - } - - @Test - public void dispatchOnCreate() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onCreate(activity, bundle); - - verify(lightCycleComponent1).onCreate(activity, bundle); - verify(lightCycleComponent2).onCreate(activity, bundle); - } - - @Test - public void dispatchOnNewIntent() { - final Intent intent = mock(Intent.class); - - dispatcher.onNewIntent(activity, intent); - - verify(lightCycleComponent1).onNewIntent(activity, intent); - verify(lightCycleComponent2).onNewIntent(activity, intent); - } - - @Test - public void dispatchOnStart() { - dispatcher.onStart(activity); - - verify(lightCycleComponent1).onStart(activity); - verify(lightCycleComponent2).onStart(activity); - } - - @Test - public void dispatchOnResume() { - dispatcher.onResume(activity); - - verify(lightCycleComponent1).onResume(activity); - verify(lightCycleComponent2).onResume(activity); - } - - @Test - public void dispatchOnPause() { - dispatcher.onPause(activity); - - verify(lightCycleComponent1).onPause(activity); - verify(lightCycleComponent2).onPause(activity); - } - - @Test - public void dispatchOnStop() { - dispatcher.onStop(activity); - - verify(lightCycleComponent1).onStop(activity); - verify(lightCycleComponent2).onStop(activity); - } - - @Test - public void dispatchOnSaveInstanceState() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onSaveInstanceState(activity, bundle); - - verify(lightCycleComponent1).onSaveInstanceState(activity, bundle); - verify(lightCycleComponent2).onSaveInstanceState(activity, bundle); - } - - @Test - public void dispatchOnRestoreInstanceState() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onRestoreInstanceState(activity, bundle); - - verify(lightCycleComponent1).onRestoreInstanceState(activity, bundle); - verify(lightCycleComponent2).onRestoreInstanceState(activity, bundle); - } - - @Test - public void dispatchOnDestroy() { - dispatcher.onDestroy(activity); - - verify(lightCycleComponent1).onDestroy(activity); - verify(lightCycleComponent2).onDestroy(activity); - } - - @Test - public void dispatchOnlyOnceToDuplicatesComponents() { - final Bundle bundle = Bundle.EMPTY; - dispatcher.bind(lightCycleComponent1); - dispatcher.bind(lightCycleComponent1); - dispatcher.onCreate(activity, bundle); - - verify(lightCycleComponent1, times(1)).onCreate(activity, bundle); - } - - @Test(expected = NullPointerException.class) - public void nullBinderTarget() { - dispatcher.bind(null); - } -} diff --git a/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/FragmentLightCycleDispatcherTest.java b/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/FragmentLightCycleDispatcherTest.java deleted file mode 100644 index 99dc04e..0000000 --- a/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/FragmentLightCycleDispatcherTest.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.soundcloud.lightcycle; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import android.app.Activity; -import android.app.Fragment; -import android.content.Context; -import android.os.Bundle; -import android.view.View; - -@RunWith(MockitoJUnitRunner.class) -public class FragmentLightCycleDispatcherTest { - @Mock private FragmentLightCycle lifeCycleComponent1; - @Mock private FragmentLightCycle lifeCycleComponent2; - @Mock private Fragment fragment; - @Mock private Activity activity; - @Mock private Context context; - private FragmentLightCycleDispatcher dispatcher; - - @Before - public void setUp() throws Exception { - dispatcher = new FragmentLightCycleDispatcher<>(); - dispatcher.bind(lifeCycleComponent1); - dispatcher.bind(lifeCycleComponent2); - } - - @Test - public void shouldNotifyOnAttach() { - dispatcher.onAttach(fragment, activity); - - verify(lifeCycleComponent1).onAttach(fragment, activity); - verify(lifeCycleComponent2).onAttach(fragment, activity); - } - - @Test - public void shouldNotifyOnAttachAPI23() { - dispatcher.onAttach(fragment, context); - - verify(lifeCycleComponent1).onAttach(fragment, context); - verify(lifeCycleComponent2).onAttach(fragment, context); - } - - @Test - public void shouldNotifyOnCreate() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onCreate(fragment, bundle); - - verify(lifeCycleComponent1).onCreate(fragment, bundle); - verify(lifeCycleComponent2).onCreate(fragment, bundle); - } - - @Test - public void shouldNotifyOnStart() { - dispatcher.onStart(fragment); - - verify(lifeCycleComponent1).onStart(fragment); - verify(lifeCycleComponent2).onStart(fragment); - } - - @Test - public void shouldNotifyOnResume() { - dispatcher.onResume(fragment); - - verify(lifeCycleComponent1).onResume(fragment); - verify(lifeCycleComponent2).onResume(fragment); - } - - @Test - public void shouldNotifyOnPause() { - dispatcher.onPause(fragment); - - verify(lifeCycleComponent1).onPause(fragment); - verify(lifeCycleComponent2).onPause(fragment); - } - - @Test - public void shouldNotifyOnStop() { - dispatcher.onStop(fragment); - - verify(lifeCycleComponent1).onStop(fragment); - verify(lifeCycleComponent2).onStop(fragment); - } - - @Test - public void shouldNotifyOnActivityCreated() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onActivityCreated(fragment, bundle); - - verify(lifeCycleComponent1).onActivityCreated(fragment, bundle); - verify(lifeCycleComponent2).onActivityCreated(fragment, bundle); - } - - @Test - public void shouldNotifyOnSaveInstanceState() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onSaveInstanceState(fragment, bundle); - - verify(lifeCycleComponent1).onSaveInstanceState(fragment, bundle); - verify(lifeCycleComponent2).onSaveInstanceState(fragment, bundle); - } - - @Test - public void shouldNotifyOnDestroy() { - dispatcher.onDestroy(fragment); - - verify(lifeCycleComponent1).onDestroy(fragment); - verify(lifeCycleComponent2).onDestroy(fragment); - } - - @Test - public void shouldNotifyOnDetach() { - dispatcher.onDetach(fragment); - - verify(lifeCycleComponent1).onDetach(fragment); - verify(lifeCycleComponent2).onDetach(fragment); - } - - @Test - public void shouldNotifyOnViewCreated() { - final Bundle bundle = Bundle.EMPTY; - final View view = mock(View.class); - - dispatcher.onViewCreated(fragment, view, bundle); - - verify(lifeCycleComponent1).onViewCreated(fragment, view, bundle); - verify(lifeCycleComponent2).onViewCreated(fragment, view, bundle); - } - - @Test - public void shouldNotifyOnDestroyView() { - dispatcher.onDestroyView(fragment); - - verify(lifeCycleComponent1).onDestroyView(fragment); - verify(lifeCycleComponent2).onDestroyView(fragment); - } - - @Test(expected = NullPointerException.class) - public void nullBinderTarget() { - dispatcher.bind(null); - } -} diff --git a/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/SupportFragmentLightCycleDispatcherTest.java b/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/SupportFragmentLightCycleDispatcherTest.java deleted file mode 100644 index 199e998..0000000 --- a/lightcycle-lib/src/test/java/com/soundcloud/lightcycle/SupportFragmentLightCycleDispatcherTest.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.soundcloud.lightcycle; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.View; - -@RunWith(MockitoJUnitRunner.class) -public class SupportFragmentLightCycleDispatcherTest { - @Mock private SupportFragmentLightCycle lifeCycleComponent1; - @Mock private SupportFragmentLightCycle lifeCycleComponent2; - @Mock private Fragment fragment; - @Mock private Activity activity; - private SupportFragmentLightCycleDispatcher dispatcher; - - @Before - public void setUp() throws Exception { - dispatcher = new SupportFragmentLightCycleDispatcher<>(); - dispatcher.bind(lifeCycleComponent1); - dispatcher.bind(lifeCycleComponent2); - } - - @Test - public void shouldNotifyOnAttach() { - dispatcher.onAttach(fragment, activity); - - verify(lifeCycleComponent1).onAttach(fragment, activity); - verify(lifeCycleComponent2).onAttach(fragment, activity); - } - - @Test - public void shouldNotifyOnCreate() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onCreate(fragment, bundle); - - verify(lifeCycleComponent1).onCreate(fragment, bundle); - verify(lifeCycleComponent2).onCreate(fragment, bundle); - } - - @Test - public void shouldNotifyOnStart() { - dispatcher.onStart(fragment); - - verify(lifeCycleComponent1).onStart(fragment); - verify(lifeCycleComponent2).onStart(fragment); - } - - @Test - public void shouldNotifyOnResume() { - dispatcher.onResume(fragment); - - verify(lifeCycleComponent1).onResume(fragment); - verify(lifeCycleComponent2).onResume(fragment); - } - - @Test - public void shouldNotifyOnPause() { - dispatcher.onPause(fragment); - - verify(lifeCycleComponent1).onPause(fragment); - verify(lifeCycleComponent2).onPause(fragment); - } - - @Test - public void shouldNotifyOnStop() { - dispatcher.onStop(fragment); - - verify(lifeCycleComponent1).onStop(fragment); - verify(lifeCycleComponent2).onStop(fragment); - } - - @Test - public void shouldNotifyOnSaveInstanceState() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onSaveInstanceState(fragment, bundle); - - verify(lifeCycleComponent1).onSaveInstanceState(fragment, bundle); - verify(lifeCycleComponent2).onSaveInstanceState(fragment, bundle); - } - - @Test - public void shouldNotifyOnActivityCreated() { - final Bundle bundle = Bundle.EMPTY; - - dispatcher.onActivityCreated(fragment, bundle); - - verify(lifeCycleComponent1).onActivityCreated(fragment, bundle); - verify(lifeCycleComponent2).onActivityCreated(fragment, bundle); - } - - @Test - public void shouldNotifyOnDestroy() { - dispatcher.onDestroy(fragment); - - verify(lifeCycleComponent1).onDestroy(fragment); - verify(lifeCycleComponent2).onDestroy(fragment); - } - - @Test - public void shouldNotifyOnDetach() { - dispatcher.onDetach(fragment); - - verify(lifeCycleComponent1).onDetach(fragment); - verify(lifeCycleComponent2).onDetach(fragment); - } - - @Test - public void shouldNotifyOnViewCreated() { - final Bundle bundle = Bundle.EMPTY; - final View view = mock(View.class); - - dispatcher.onViewCreated(fragment, view, bundle); - - verify(lifeCycleComponent1).onViewCreated(fragment, view, bundle); - verify(lifeCycleComponent2).onViewCreated(fragment, view, bundle); - } - - @Test - public void shouldNotifyOnDestroyView() { - dispatcher.onDestroyView(fragment); - - verify(lifeCycleComponent1).onDestroyView(fragment); - verify(lifeCycleComponent2).onDestroyView(fragment); - } - - @Test(expected = NullPointerException.class) - public void nullBinderTarget() { - dispatcher.bind(null); - } -} diff --git a/lightcycle-processor/build.gradle b/lightcycle-processor/build.gradle deleted file mode 100644 index cd3fdb4..0000000 --- a/lightcycle-processor/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -apply plugin: 'checkstyle' -apply from: rootProject.file('gradle/gradle-mvn-push.gradle') - -checkstyle { - configFile rootProject.file('checkstyle.xml') - showViolations true -} - -dependencies { - compile project(':lightcycle-api') - compile deps.javapoet - - testCompile deps.android - testCompile deps.support_v4 - testCompile deps.compiletesting - // compile-testing fails with JavacTool ClassNotFoundException, so add tools.jar manually - // (this should be the correct cross-platform solution to do this) - // cf. http://stackoverflow.com/questions/11345193/gradle-does-not-find-tools-jar - testCompile files(((URLClassLoader) javax.tools.ToolProvider.getSystemToolClassLoader()).getURLs()) -} diff --git a/lightcycle-processor/gradle.properties b/lightcycle-processor/gradle.properties deleted file mode 100644 index c2d8eb3..0000000 --- a/lightcycle-processor/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -POM_NAME=LightCycle processor -POM_ARTIFACT_ID=lightcycle-processor -POM_PACKAGING=jar diff --git a/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleBinder.java b/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleBinder.java deleted file mode 100644 index a92c0b9..0000000 --- a/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleBinder.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.squareup.javapoet.CodeBlock; - -import javax.annotation.processing.Messager; -import javax.lang.model.element.Element; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; -import javax.tools.Diagnostic; -import java.util.List; - -abstract class LightCycleBinder { - private static final String METHOD_BIND_NAME = "bind"; - private static final String METHOD_BIND_ARGUMENT_NAME = "target"; - private static final String METHOD_LIFT_NAME = LightCycleProcessor.LIB_PACKAGE + ".LightCycles.lift"; - - private static final CodeBlock EMPTY_BLOCK = CodeBlock.builder().build(); - - static final LightCycleBinder DISPATCHER_NOT_FOUND = new LightCycleBinder() { - @Override - CodeBlock generateBind(Messager messager, Element element) { - messager.printMessage(Diagnostic.Kind.ERROR, "Could not find dispatcher type. Did you forget to add the generic type?", element); - return EMPTY_BLOCK; - } - }; - - static final LightCycleBinder EMPTY = new LightCycleBinder() { - @Override - CodeBlock generateBind(Messager messager, Element element) { - return EMPTY_BLOCK; - } - }; - - static LightCycleBinder forFields(final LightCycleDispatcherKind dispatcherKind, final DeclaredType type) { - return new LightCycleBinder() { - @Override - CodeBlock generateBind(Messager messager, Element element) { - final String liftedName = element.getSimpleName() + "$Lifted"; - - final List typeArguments = type.getTypeArguments(); - if (typeArguments.size() != 1) { - error(messager, typeArguments); - return EMPTY_BLOCK; - } else { - return generateLiftAndBind(element, liftedName, typeArguments); - } - } - - private CodeBlock generateLiftAndBind(Element element, String liftedName, List typeArguments) { - final String lightCycleLiftedType = dispatcherKind.toTypeName(typeArguments.get(0).toString()); - return CodeBlock.builder() - .addStatement("final $N $N = $N($N.$N)", - lightCycleLiftedType, - liftedName, - METHOD_LIFT_NAME, - METHOD_BIND_ARGUMENT_NAME, - element.getSimpleName()) - .addStatement("$N.$N($N)", METHOD_BIND_ARGUMENT_NAME, METHOD_BIND_NAME, liftedName) - .build(); - } - - private void error(Messager messager, List typeArguments) { - final String message = String.format("%s: Expected 1 type argument but found %d. TypeArguments:[%s]. Did you forget to add generic types?", - type.toString(), - typeArguments.size(), - typeArguments.toString()); - messager.printMessage(Diagnostic.Kind.ERROR, message, type.asElement()); - } - }; - } - - static LightCycleBinder forParent(final String parentName) { - return new LightCycleBinder() { - @Override - CodeBlock generateBind(Messager messager, Element element) { - return CodeBlock.builder().addStatement("$N.$N($N)", parentName, METHOD_BIND_NAME, METHOD_BIND_ARGUMENT_NAME).build(); - } - }; - } - - abstract CodeBlock generateBind(Messager messager, Element element); -} diff --git a/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleDispatcherKind.java b/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleDispatcherKind.java deleted file mode 100644 index 7d08c0a..0000000 --- a/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleDispatcherKind.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.soundcloud.lightcycle; - -import javax.lang.model.element.Name; - -enum LightCycleDispatcherKind { - DEFAULT_ACTIVITIES { - @Override - boolean matches(Name name) { - return name.contentEquals("LightCycleAppCompatActivity") || name.contentEquals("LightCycleActionBarActivity"); - } - - @Override - String toTypeName(String dispatchedType) { - return typeArgumentAsString("ActivityLightCycle", dispatchedType); - } - }, - DEFAULT_FRAGMENT { - @Override - boolean matches(Name name) { - return name.contentEquals("LightCycleFragment"); - } - - @Override - String toTypeName(String dispatchedType) { - return typeArgumentAsString("FragmentLightCycle", dispatchedType); - } - }, - DEFAULT_SUPPORT_FRAGMENT { - @Override - boolean matches(Name name) { - return name.contentEquals("LightCycleSupportFragment"); - } - - @Override - String toTypeName(String dispatchedType) { - return typeArgumentAsString("SupportFragmentLightCycle", dispatchedType); - } - }, - DEFAULT_PREFERENCE_FRAGMENT { - @Override - boolean matches(Name name) { - return name.contentEquals("LightCyclePreferenceFragmentCompat"); - } - - @Override - String toTypeName(String dispatchedType) { - return typeArgumentAsString("SupportFragmentLightCycle", dispatchedType); - } - }, - DEFAULT_SUPPORT_DIALOG_FRAGMENT { - @Override - boolean matches(Name name) { - return name.contentEquals("LightCycleSupportDialogFragment"); - } - - @Override - String toTypeName(String dispatchedType) { - return typeArgumentAsString("SupportFragmentLightCycle", dispatchedType); - } - }, - BASE_ACTIVITY_DISPATCHER { - @Override - boolean matches(Name name) { - return name.contentEquals("ActivityLightCycleDispatcher"); - } - - @Override - String toTypeName(String dispatchedType) { - return typeArgumentAsString("ActivityLightCycle", dispatchedType); - } - }, - BASE_SUPPORT_FRAGMENT_DISPATCHER { - @Override - boolean matches(Name name) { - return name.contentEquals("SupportFragmentLightCycleDispatcher"); - } - - @Override - String toTypeName(String dispatchedType) { - return typeArgumentAsString("SupportFragmentLightCycle", dispatchedType); - } - }, - BASE_FRAGMENT_DISPATCHER { - @Override - boolean matches(Name name) { - return name.contentEquals("FragmentLightCycleDispatcher"); - } - - @Override - String toTypeName(String dispatchedType) { - return typeArgumentAsString("FragmentLightCycle", dispatchedType); - } - }, - DISPATCHER_INTERFACE { - @Override - boolean matches(Name name) { - return name.contentEquals("LightCycleDispatcher"); - } - - @Override - String toTypeName(String dispatchedType) { - return dispatchedType; - } - - }; - - private static String typeArgumentAsString(String lightCycleType, String componentType) { - return String.format("%s.%s<%s>", LightCycleProcessor.LIB_PACKAGE, lightCycleType, componentType); - } - - abstract boolean matches(Name name); - - abstract String toTypeName(String dispatchedType); -} diff --git a/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleProcessor.java b/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleProcessor.java deleted file mode 100644 index 7ed18f7..0000000 --- a/lightcycle-processor/src/main/java/com/soundcloud/lightcycle/LightCycleProcessor.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.TypeSpec; - -import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.ProcessingEnvironment; -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.annotation.processing.SupportedSourceVersion; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.PackageElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; -import javax.tools.Diagnostic; -import javax.tools.JavaFileObject; -import java.io.IOException; -import java.io.Writer; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -@SupportedAnnotationTypes("com.soundcloud.lightcycle.LightCycle") -@SupportedSourceVersion(SourceVersion.RELEASE_7) -public class LightCycleProcessor extends AbstractProcessor { - - static final String LIB_PACKAGE = "com.soundcloud.lightcycle"; - private static final String ANNOTATION_CLASS = LIB_PACKAGE + ".LightCycle"; - private static final String CLASS_BINDER_NAME = "LightCycleBinder"; - private static final String METHOD_BIND_NAME = "bind"; - private static final String METHOD_BIND_ARGUMENT_NAME = "target"; - - private Elements elementUtils; - private Types typeUtils; - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - - typeUtils = processingEnv.getTypeUtils(); - elementUtils = processingEnv.getElementUtils(); - } - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - final TypeElement lightCycleAnnotation = processingEnv.getElementUtils().getTypeElement(ANNOTATION_CLASS); - final Set annotatedFields = roundEnvironment.getElementsAnnotatedWith(lightCycleAnnotation); - if (annotatedFields.isEmpty()) { - return true; - } - - verifyFieldsAccessible(annotatedFields); - - note("processing " + annotatedFields.size() + " fields"); - - Map> lightCyclesByHostElement = new HashMap<>(); - Set erasedTargetNames = new HashSet<>(); - for (Element lightCycle : annotatedFields) { - final Element hostElement = lightCycle.getEnclosingElement(); - List lightCycles = lightCyclesByHostElement.get(hostElement); - if (lightCycles == null) { - lightCycles = new LinkedList<>(); - erasedTargetNames.add(hostElement.toString()); - lightCyclesByHostElement.put(hostElement, lightCycles); - } - lightCycles.add(lightCycle); - } - - try { - for (Map.Entry> entry : lightCyclesByHostElement.entrySet()) { - generateBinder(erasedTargetNames, entry.getValue(), entry.getKey()); - } - } catch (IOException e) { - throw new RuntimeException("Failed writing class file", e); - } - - return true; - } - - private void generateBinder(Set erasedTargetNames, List elements, Element hostElement) - throws IOException { - PackageElement packageElement = processingEnv.getElementUtils().getPackageOf(hostElement); - final String simpleClassName = binderName(hostElement.getSimpleName().toString()); - final String qualifiedClassName = packageElement.getQualifiedName() + "." + simpleClassName; - - note("writing class " + qualifiedClassName); - JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile( - qualifiedClassName, elements.toArray(new Element[elements.size()])); - - ClassName hostElementName = ClassName.bestGuess(hostElement.getSimpleName().toString()); - MethodSpec bindMethod = MethodSpec.methodBuilder(METHOD_BIND_NAME) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(void.class) - .addParameter(hostElementName, METHOD_BIND_ARGUMENT_NAME) - .addCode(generateBindMethod(erasedTargetNames, hostElement, elements)) - .build(); - - TypeSpec classType = TypeSpec.classBuilder(simpleClassName) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addMethod(bindMethod) - .build(); - - final Writer writer = sourceFile.openWriter(); - JavaFile.builder(packageElement.getQualifiedName().toString(), classType) - .build() - .writeTo(writer); - writer.close(); - } - - private String binderName(String name) { - return name + "$" + CLASS_BINDER_NAME; - } - - private CodeBlock generateBindMethod(Set erasedTargetNames, Element hostElement, List elements) { - return CodeBlock.builder() - .add(emitBindParent(erasedTargetNames, hostElement)) - .add(emitBindLightCycles(hostElement, elements)) - .build(); - } - - private CodeBlock emitBindParent(Set erasedTargetNames, Element hostElement) { - final TypeElement typeElement = (TypeElement) hostElement; - - LightCycleBinder parentName = findParent(erasedTargetNames, typeElement.getSuperclass()); - return parentName.generateBind(processingEnv.getMessager(), hostElement); - } - - private CodeBlock emitBindLightCycles(Element hostElement, List elements) { - final LightCycleBinder binder = findBinder((TypeElement) hostElement); - CodeBlock.Builder cb = CodeBlock.builder(); - for (Element element : elements) { - cb.add(binder.generateBind(processingEnv.getMessager(), element)); - } - return cb.build(); - } - - private LightCycleBinder findBinder(TypeElement element) { - if (element == null) { - return LightCycleBinder.DISPATCHER_NOT_FOUND; - } - - final TypeMirror elementType = element.asType(); - if (elementType.getKind() != TypeKind.DECLARED) { - return LightCycleBinder.DISPATCHER_NOT_FOUND; - } - - for (TypeMirror typeMirror : typeUtils.directSupertypes(elementType)) { - for (LightCycleDispatcherKind dispatcherKind : LightCycleDispatcherKind.values()) { - if (dispatcherKind.matches(typeUtils.asElement(typeMirror).getSimpleName())) { - return LightCycleBinder.forFields(dispatcherKind, ((DeclaredType) typeMirror)); - } - } - } - - return findBinder((TypeElement) typeUtils.asElement(element.getSuperclass())); - } - - private LightCycleBinder findParent(Set erasedTargetNames, TypeMirror type) { - if (type.getKind() == TypeKind.NONE) { - return LightCycleBinder.EMPTY; - } - - final TypeElement typeElement = (TypeElement) ((DeclaredType) type).asElement(); - if (erasedTargetNames.contains(typeElement.toString())) { - final String parentWithLightCycle = elementUtils.getBinaryName(typeElement).toString(); - return LightCycleBinder.forParent(binderName(parentWithLightCycle)); - } - return findParent(erasedTargetNames, typeElement.getSuperclass()); - } - - private void verifyFieldsAccessible(Set elements) { - for (Element element : elements) { - if (element.getModifiers().contains(Modifier.PRIVATE)) { - throw new IllegalStateException("Annotated fields cannot be private: " - + element.getEnclosingElement() + "#" + element + "(" + element.asType() + ")"); - } - } - } - - private void note(String message) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "LightCycleProcessor: " + message); - } -} diff --git a/lightcycle-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/lightcycle-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index 088d045..0000000 --- a/lightcycle-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1 +0,0 @@ -com.soundcloud.lightcycle.LightCycleProcessor diff --git a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/ActivityInjectionTest.java b/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/ActivityInjectionTest.java deleted file mode 100644 index 7e633da..0000000 --- a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/ActivityInjectionTest.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; - -import org.junit.Test; - -import javax.tools.JavaFileObject; - -import static com.google.common.truth.Truth.assertAbout; -import static com.google.testing.compile.JavaFileObjects.forSourceString; -import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; -import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources; - -public class ActivityInjectionTest { - - @Test - public void shouldGenerateInjectorForActivity() { - JavaFileObject validTestActivity = forSourceString("com/test/ValidTestActivity", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.ActivityLightCycle;", - "import com.soundcloud.lightcycle.DefaultActivityLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "", - "import android.app.Activity;", - "", - "public class ValidTestActivity ", - " extends Activity ", - " implements LightCycleDispatcher> {", - "", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - " @Override", - " public void bind(ActivityLightCycle lightCycle) {", - " // nop", - " }", - "", - "}", - "", - "class LightCycle1 extends DefaultActivityLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultActivityLightCycle {", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestActivity$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestActivity$LightCycleBinder {", - "", - " public static void bind(ValidTestActivity target) {", - " final com.soundcloud.lightcycle.ActivityLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.ActivityLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSource()) - .that(validTestActivity) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } - - @Test - public void shouldGenerateInjectorForActivityHierarchy() { - JavaFileObject validTestHierarchyActivity = forSourceString("com/test/ValidTestHierarchyActivity", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.ActivityLightCycle;", - "import com.soundcloud.lightcycle.DefaultActivityLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "", - "import android.app.Activity;", - "", - "public class ValidTestHierarchyActivity extends BaseActivity {", - " @LightCycle LightCycle2 lightCycle2;", - "", - "}", - "", - "class BaseActivity ", - " extends Activity ", - " implements LightCycleDispatcher> {", - "", - " @LightCycle LightCycle1 lightCycle1;", - "", - " @Override", - " public void bind(ActivityLightCycle lightCycle) {", - " // nop", - " }", - "", - "}", - "", - "class LightCycle1 extends DefaultActivityLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultActivityLightCycle {", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestHierarchyActivity$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestHierarchyActivity$LightCycleBinder {", - "", - " public static void bind(ValidTestHierarchyActivity target) {", - " com.test.BaseActivity$LightCycleBinder.bind(target);", - " final com.soundcloud.lightcycle.ActivityLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSource()) - .that(validTestHierarchyActivity) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } - - @Test - public void shouldGenerateInjectorForLightCycleAppCompatActivity() { - JavaFileObject validTestLightCycleAppCompatActivity = forSourceString("com/test/ValidTestLightCycleAppCompatActivity", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.ActivityLightCycle;", - "import com.soundcloud.lightcycle.DefaultActivityLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.LightCycleAppCompatActivity;", - "", - "import android.app.Activity;", - "", - "public class ValidTestLightCycleAppCompatActivity ", - " extends LightCycleAppCompatActivity {", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - "}", - "", - "class LightCycle1 extends DefaultActivityLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultActivityLightCycle {", - "}")); - - // Because neither the processor or the lib (java libraries) can depend on the api (Android library), - // we have to create a fake `LightCycleAppCompatActivity` here for testing purpose. - JavaFileObject fakeLightCycleAppCompatActivity = forSourceString("com/soundcloud/lightcycle/LightCycleAppCompatActivity", Joiner.on("\n").join( - "package com.soundcloud.lightcycle;", - "", - "import android.app.Activity;", - "", - "public abstract class LightCycleAppCompatActivity", - " extends Activity", - " implements LightCycleDispatcher> {", - "", - " @Override", - " public void bind(ActivityLightCycle lightCycle) { }", - "", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestLightCycleAppCompatActivity$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestLightCycleAppCompatActivity$LightCycleBinder {", - "", - " public static void bind(ValidTestLightCycleAppCompatActivity target) {", - " final com.soundcloud.lightcycle.ActivityLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.ActivityLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSources()) - .that(ImmutableList.of(validTestLightCycleAppCompatActivity, fakeLightCycleAppCompatActivity)) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } - - @Test - public void shouldGenerateInjectorForLightCycleActionBarActivity() { - JavaFileObject validTestLightCycleActionBarActivity = forSourceString("com/test/ValidTestLightCycleActionBarActivity", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.ActivityLightCycle;", - "import com.soundcloud.lightcycle.DefaultActivityLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.LightCycleActionBarActivity;", - "", - "import android.app.Activity;", - "", - "public class ValidTestLightCycleActionBarActivity ", - " extends LightCycleActionBarActivity {", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - "}", - "", - "class LightCycle1 extends DefaultActivityLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultActivityLightCycle {", - "}")); - - // Because neither the processor or the lib (java libraries) can depend on the api (Android library), - // we have to create a fake `LightCycleActionBarActivity` here for testing purpose. - JavaFileObject fakeLightCycleActionBarActivity = forSourceString("com/soundcloud/lightcycle/LightCycleActionBarActivity", Joiner.on("\n").join( - "package com.soundcloud.lightcycle;", - "", - "import android.app.Activity;", - "", - "public abstract class LightCycleActionBarActivity", - " extends Activity", - " implements LightCycleDispatcher> {", - "", - " @Override", - " public void bind(ActivityLightCycle lightCycle) { }", - "", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestLightCycleActionBarActivity$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestLightCycleActionBarActivity$LightCycleBinder {", - "", - " public static void bind(ValidTestLightCycleActionBarActivity target) {", - " final com.soundcloud.lightcycle.ActivityLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.ActivityLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSources()) - .that(ImmutableList.of(validTestLightCycleActionBarActivity, fakeLightCycleActionBarActivity)) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } -} diff --git a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/FragmentInjectionTest.java b/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/FragmentInjectionTest.java deleted file mode 100644 index fda6a09..0000000 --- a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/FragmentInjectionTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; - -import org.junit.Test; - -import javax.tools.JavaFileObject; - -import static com.google.common.truth.Truth.assertAbout; -import static com.google.testing.compile.JavaFileObjects.forSourceString; -import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; -import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources; - -public class FragmentInjectionTest { - - @Test - public void shouldGenerateInjectorForFragment() { - JavaFileObject validTestFragment = forSourceString("com/test/ValidTestFragment", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.FragmentLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.DefaultFragmentLightCycle;", - "", - "import android.app.Fragment;", - "", - "public class ValidTestFragment extends Fragment ", - " implements LightCycleDispatcher> {", - "", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - " @Override", - " public void bind(FragmentLightCycle lightCycle) {", - " // nop", - " }", - "", - "}", - "", - "class LightCycle1 extends DefaultFragmentLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultFragmentLightCycle {", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestFragment$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestFragment$LightCycleBinder {", - "", - " public static void bind(ValidTestFragment target) {", - " final com.soundcloud.lightcycle.FragmentLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.FragmentLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSource()) - .that(validTestFragment) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } - - @Test - public void shouldGenerateInjectorForLightCycleFragment() { - JavaFileObject validTestLightCycleFragment = forSourceString("com/test/ValidTestLightCycleFragment", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.DefaultFragmentLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.LightCycleFragment;", - "", - "import android.app.Activity;", - "", - "public class ValidTestLightCycleFragment ", - " extends LightCycleFragment {", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - "}", - "", - "class LightCycle1 extends DefaultFragmentLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultFragmentLightCycle {", - "}")); - - // Because neither the processor or the lib (java libraries) can depend on the api (Android library), - // we have to create a fake `LightCycleFragment` here for testing purpose. - JavaFileObject fakeLightCycleFragment = forSourceString("com/soundcloud/lightcycle/LightCycleFragment", Joiner.on("\n").join( - "package com.soundcloud.lightcycle;", - "", - "import android.app.Fragment;", - "", - "public abstract class LightCycleFragment", - " extends Fragment", - " implements LightCycleDispatcher> {", - "", - " @Override", - " public void bind(FragmentLightCycle lifeCycleComponent) { }", - "", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestLightCycleFragment$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestLightCycleFragment$LightCycleBinder {", - "", - " public static void bind(ValidTestLightCycleFragment target) {", - " final com.soundcloud.lightcycle.FragmentLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.FragmentLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSources()) - .that(ImmutableList.of(validTestLightCycleFragment, fakeLightCycleFragment)) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } -} diff --git a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/InvalidCaseTest.java b/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/InvalidCaseTest.java deleted file mode 100644 index 3bba7be..0000000 --- a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/InvalidCaseTest.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.google.common.base.Joiner; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import javax.tools.JavaFileObject; - -import static com.google.common.truth.Truth.assertAbout; -import static com.google.testing.compile.JavaFileObjects.forSourceString; -import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; - -public class InvalidCaseTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void shouldThrowExceptionWhenLightCycleFieldIsPrivate() { - expectedException.expect(RuntimeException.class); - expectedException.expectMessage("Annotated fields cannot be private: " - + "com.test.PrivateFieldsTestFragment#lightCycle1(com.test.LightCycle1)"); - - JavaFileObject privateFieldsTestFragment = forSourceString("com/test/PrivateFieldsTestFragment", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.DefaultSupportFragmentLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.SupportFragmentLightCycle;", - "", - "import android.support.v4.app.Fragment;", - "", - "public class PrivateFieldsTestFragment extends Fragment ", - " implements LightCycleDispatcher {", - "", - " private @LightCycle LightCycle1 lightCycle1;", - " private @LightCycle LightCycle2 lightCycle2;", - "", - " @Override", - " public void bind(SupportFragmentLightCycle lightCycle) {", - " // nop", - " }", - "", - "}", - "", - "class LightCycle1 extends DefaultSupportFragmentLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultSupportFragmentLightCycle {", - "}")); - - assertAbout(javaSource()) - .that(privateFieldsTestFragment) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError(); - } - - @Test - public void lightCycleFieldIsNotALightCycle() { - JavaFileObject privateFieldsTestFragment = forSourceString("com/test/FieldsNotLightCyclesTestFragment", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.DefaultSupportFragmentLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.SupportFragmentLightCycle;", - "", - "import android.support.v4.app.Fragment;", - "", - "public class FieldsNotLightCyclesTestFragment extends Fragment ", - " implements LightCycleDispatcher {", - "", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - " @Override", - " public void bind(SupportFragmentLightCycle lightCycle) {", - " // nop", - " }", - "", - "}", - "", - "class LightCycle1 {", - "}", - "", - "class LightCycle2 {", - "}")); - - assertAbout(javaSource()) - .that(privateFieldsTestFragment) - .processedWith(new LightCycleProcessor()) - .failsToCompile() - .withErrorContaining("no suitable method found for lift(com.test.LightCycle1)"); - } - - @Test - public void missingGenericTestActivity() { - JavaFileObject missingGenericTestActivity = forSourceString("com/test/MissingGenericTestActivity", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.ActivityLightCycle;", - "import com.soundcloud.lightcycle.DefaultActivityLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.LightCycleActionBarActivity;", - "", - "import android.app.Activity;", - "", - "public class MissingGenericTestActivity extends LightCycleActionBarActivity {", - "", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - " @Override", - " public void bind(ActivityLightCycle lightCycle) {", - " // nop", - " }", - "", - "}", - "", - "class LightCycle1 extends DefaultActivityLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultActivityLightCycle {", - "}")); - - assertAbout(javaSource()) - .that(missingGenericTestActivity) - .processedWith(new LightCycleProcessor()) - .failsToCompile() - .withErrorContaining("Expected 1 type argument but found 0. TypeArguments:[]. " - + "Did you forget to add generic types?"); - } - - @Test - public void dispatcherNotFound() { - JavaFileObject dispatcherNotFoundTestActivity = forSourceString("com/test/DispatcherNotFoundTestActivity", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.ActivityLightCycle;", - "import com.soundcloud.lightcycle.DefaultActivityLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "", - "import android.app.Activity;", - "", - "public class DispatcherNotFoundTestActivity extends Activity {", - "", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - "}", - "", - "class LightCycle1 extends DefaultActivityLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultActivityLightCycle {", - "}")); - - assertAbout(javaSource()) - .that(dispatcherNotFoundTestActivity) - .processedWith(new LightCycleProcessor()) - .failsToCompile() - .withErrorContaining("Could not find dispatcher type. " - + "Did you forget to add the generic type?"); - } -} diff --git a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/ParameterizedDispatcherTest.java b/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/ParameterizedDispatcherTest.java deleted file mode 100644 index d6f023b..0000000 --- a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/ParameterizedDispatcherTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; - -import org.junit.Test; - -import javax.tools.JavaFileObject; - -import static com.google.common.truth.Truth.assertAbout; -import static com.google.testing.compile.JavaFileObjects.forSourceString; -import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources; - -public class ParameterizedDispatcherTest { - - @Test - public void shouldGenerateInjectorForParameterizedDispatcher() { - JavaFileObject validTestParameterizedDispatcher = forSourceString("com/test/ValidTestParameterizedDispatcher", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.FragmentLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.FragmentLightCycleDispatcher;", - "import com.soundcloud.lightcycle.DefaultFragmentLightCycle;", - "", - "import android.app.Fragment;", - "", - "public class ValidTestParameterizedDispatcher ", - " extends FragmentLightCycleDispatcher{", - "", - " @LightCycle DefaultFragmentLightCycle lightCycle1;", - " @LightCycle DefaultFragmentLightCycle lightCycle2;", - "", - "}")); - - // Because neither the processor or the lib (java libraries) can depend on the api (Android library), - // we have to create a fake `LightCycleActionBarActivity` here for testing purpose. - JavaFileObject fakeFragmentLightCycleDispatcher = forSourceString("com/soundcloud/lightcycle/FragmentLightCycleDispatcher", Joiner.on("\n").join( - "package com.soundcloud.lightcycle;", - "", - "import android.annotation.TargetApi;", - "import android.app.Activity;", - "import android.app.Fragment;", - "import android.content.Context;", - "import android.os.Build;", - "import android.os.Bundle;", - "import android.view.MenuItem;", - "import android.view.View;", - "", - "@TargetApi(Build.VERSION_CODES.HONEYCOMB)", - "public class FragmentLightCycleDispatcher", - " implements LightCycleDispatcher>, FragmentLightCycle {", - "", - " public FragmentLightCycleDispatcher() {", - " }", - "", - " @Override", - " public void bind(FragmentLightCycle lightCycle) { }", - "", - " @Override", - " public void onAttach(T fragment, Activity activity) { }", - "", - " @Override", - " public void onAttach(T fragment, Context context) { }", - "", - " @Override", - " public void onCreate(T fragment, Bundle bundle) { }", - "", - " @Override", - " public void onViewCreated(T fragment, View view, Bundle savedInstanceState) { }", - "", - " @Override", - " public void onActivityCreated(T fragment, Bundle bundle) { }", - "", - " @Override", - " public void onStart(T fragment) { }", - "", - " @Override", - " public void onResume(T fragment) { }", - "", - " @Override", - " public boolean onOptionsItemSelected(T fragment, MenuItem item) {", - " return false;", - " }", - "", - " @Override", - " public void onPause(T fragment) { }", - "", - " @Override", - " public void onStop(T fragment) { }", - "", - " @Override", - " public void onSaveInstanceState(T fragment, Bundle bundle) { }", - "", - " @Override", - " public void onDestroyView(T fragment) { }", - "", - " @Override", - " public void onDestroy(T fragment) { }", - "", - " @Override", - " public void onDetach(T fragment) { }", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestParameterizedDispatcher$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestParameterizedDispatcher$LightCycleBinder {", - "", - " public static void bind(ValidTestParameterizedDispatcher target) {", - " final com.soundcloud.lightcycle.FragmentLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.FragmentLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSources()) - .that(ImmutableList.of(validTestParameterizedDispatcher, fakeFragmentLightCycleDispatcher)) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } -} diff --git a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/SupportFragmentInjectionTest.java b/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/SupportFragmentInjectionTest.java deleted file mode 100644 index 6bf5acd..0000000 --- a/lightcycle-processor/src/test/java/com/soundcloud/lightcycle/SupportFragmentInjectionTest.java +++ /dev/null @@ -1,200 +0,0 @@ -package com.soundcloud.lightcycle; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; - -import org.junit.Test; - -import javax.tools.JavaFileObject; - -import static com.google.common.truth.Truth.assertAbout; -import static com.google.testing.compile.JavaFileObjects.forSourceString; -import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; -import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources; - -public class SupportFragmentInjectionTest { - - @Test - public void shouldGenerateInjectorForSupportFragment() { - JavaFileObject validTestSupportFragment = forSourceString("com/test/ValidTestSupportFragment", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.DefaultSupportFragmentLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.SupportFragmentLightCycle;", - "", - "import android.support.v4.app.Fragment;", - "", - "public class ValidTestSupportFragment extends Fragment ", - " implements LightCycleDispatcher> {", - "", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - " @Override", - " public void bind(SupportFragmentLightCycle lightCycle) {", - " // nop", - " }", - "", - "}", - "", - "class LightCycle1 extends DefaultSupportFragmentLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultSupportFragmentLightCycle {", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestSupportFragment$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestSupportFragment$LightCycleBinder {", - "", - " public static void bind(ValidTestSupportFragment target) {", - " final com.soundcloud.lightcycle.SupportFragmentLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.SupportFragmentLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSource()) - .that(validTestSupportFragment) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } - - @Test - public void shouldGenerateInjectorForLightCycleSupportFragment() { - JavaFileObject validTestLightCycleSupportFragment = forSourceString("com/test/ValidTestLightCycleSupportFragment", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.ActivityLightCycle;", - "import com.soundcloud.lightcycle.DefaultSupportFragmentLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.LightCycleSupportFragment;", - "", - "import android.app.Activity;", - "", - "public class ValidTestLightCycleSupportFragment ", - " extends LightCycleSupportFragment {", - " @LightCycle LightCycle1 lightCycle1;", - " @LightCycle LightCycle2 lightCycle2;", - "", - "}", - "", - "class LightCycle1 extends DefaultSupportFragmentLightCycle {", - "}", - "", - "class LightCycle2 extends DefaultSupportFragmentLightCycle {", - "}")); - - // Because neither the processor or the lib (java libraries) can depend on the api (Android library), - // we have to create a fake `LightCycleSupportFragment` here for testing purpose. - JavaFileObject fakeLightCycleSupportFragment = forSourceString("com/soundcloud/lightcycle/LightCycleSupportFragment", Joiner.on("\n").join( - "package com.soundcloud.lightcycle;", - "", - "import android.support.v4.app.Fragment;", - "", - "public abstract class LightCycleSupportFragment", - " extends Fragment", - " implements LightCycleDispatcher> {", - "", - " @Override", - " public void bind(SupportFragmentLightCycle lifeCycleComponent) { }", - "", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestLightCycleSupportFragment$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestLightCycleSupportFragment$LightCycleBinder {", - "", - " public static void bind(ValidTestLightCycleSupportFragment target) {", - " final com.soundcloud.lightcycle.SupportFragmentLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.SupportFragmentLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSources()) - .that(ImmutableList.of(validTestLightCycleSupportFragment, fakeLightCycleSupportFragment)) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } - - @Test - public void shouldGenerateInjectorForLightCycleSupportDialogFragment() { - JavaFileObject validTestLightCycleSupportDialogFragment = forSourceString("com/test/ValidTestLightCycleSupportDialogFragment", Joiner.on("\n").join( - "package com.test;", - "", - "import com.soundcloud.lightcycle.ActivityLightCycle;", - "import com.soundcloud.lightcycle.DefaultSupportFragmentLightCycle;", - "import com.soundcloud.lightcycle.LightCycle;", - "import com.soundcloud.lightcycle.LightCycleDispatcher;", - "import com.soundcloud.lightcycle.LightCycleSupportDialogFragment;", - "", - "import android.app.Activity;", - "", - "public class ValidTestLightCycleSupportDialogFragment ", - " extends LightCycleSupportDialogFragment {", - " @LightCycle DialogLightCycle1 lightCycle1;", - " @LightCycle DialogLightCycle2 lightCycle2;", - "", - "}", - "", - "class DialogLightCycle1 ", - " extends DefaultSupportFragmentLightCycle {", - "}", - "", - "class DialogLightCycle2 ", - " extends DefaultSupportFragmentLightCycle {", - "}")); - - // Because neither the processor or the lib (java libraries) can depend on the api (Android library), - // we have to create a fake `LightCycleSupportDialogFragment` here for testing purpose. - JavaFileObject fakeLightCycleSupportDialogFragment = forSourceString("com/soundcloud/lightcycle/LightCycleSupportDialogFragment", Joiner.on("\n").join( - "package com.soundcloud.lightcycle;", - "", - "import android.support.v4.app.DialogFragment;", - "import android.support.v4.app.Fragment;", - "", - "public abstract class LightCycleSupportDialogFragment", - " extends DialogFragment", - " implements LightCycleDispatcher> {", - "", - " @Override", - " public void bind(SupportFragmentLightCycle lifeCycleComponent) { }", - "", - "}")); - - JavaFileObject expectedSource = forSourceString("com.test.ValidTestLightCycleSupportDialogFragment$LightCycleBinder", Joiner.on("\n").join( - "package com.test;", - "", - "public final class ValidTestLightCycleSupportDialogFragment$LightCycleBinder {", - "", - " public static void bind(ValidTestLightCycleSupportDialogFragment target) {", - " final com.soundcloud.lightcycle.SupportFragmentLightCycle lightCycle1$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle1);", - " target.bind(lightCycle1$Lifted);", - " final com.soundcloud.lightcycle.SupportFragmentLightCycle lightCycle2$Lifted = ", - " com.soundcloud.lightcycle.LightCycles.lift(target.lightCycle2);", - " target.bind(lightCycle2$Lifted);", - " }", - "}")); - - assertAbout(javaSources()) - .that(ImmutableList.of(validTestLightCycleSupportDialogFragment, fakeLightCycleSupportDialogFragment)) - .processedWith(new LightCycleProcessor()) - .compilesWithoutError() - .and().generatesSources(expectedSource); - } -} diff --git a/release.sh b/release.sh deleted file mode 100755 index 556d9ac..0000000 --- a/release.sh +++ /dev/null @@ -1,23 +0,0 @@ - -set -e -set -x - -VERSION=$1 - -updateToVersion() { - version=$1 - sed -i"" "s/VERSION_NAME=.*/VERSION_NAME=$version/" gradle.properties - git add gradle.properties - git diff --quiet --exit-code --cached || git commit -m "Bump version to $version" -} - -release() { - updateToVersion "$VERSION" - git tag $VERSION - git push origin "$VERSION" - git push origin master - ./gradlew uploadArchives -} - -git checkout master && git pull -release diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 15deecf..0000000 --- a/settings.gradle +++ /dev/null @@ -1,6 +0,0 @@ -include ':lightcycle-api' -include ':lightcycle-lib' -include ':lightcycle-processor' -include ':lightcycle-integration-test' -include ':examples:basic' -include ':examples:real-world'