summaryrefslogtreecommitdiffstats
path: root/import-layers/yocto-poky/bitbake/lib/toaster
diff options
context:
space:
mode:
Diffstat (limited to 'import-layers/yocto-poky/bitbake/lib/toaster')
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcollector/admin.py22
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/bbcontroller.py4
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py49
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py100
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/loadconf.py183
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py84
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0004_auto_20160523_1446.py34
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0005_reorder_buildrequest_states.py19
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0006_brlayer_local_source_dir.py19
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0007_brlayers_optional_gitinfo.py29
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/models.py38
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/tests.py23
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/config.py2
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/log/.create0
-rwxr-xr-ximport-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/runner.py4
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/shellutils.py2
-rwxr-xr-ximport-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/run_toastertests.py4
-rwxr-xr-ximport-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py186
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/urlcheck.py4
-rwxr-xr-ximport-layers/yocto-poky/bitbake/lib/toaster/manage.py2
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/README30
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/oe-core.xml59
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/poky.xml111
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/settings.xml33
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/management/commands/lsupdates.py334
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0007_auto_20160523_1446.py89
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0008_refactor_artifact_models.py39
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0009_target_package_manifest_path.py19
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0010_delete_layer_source_references.py118
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0011_delete_layersource.py17
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0012_use_release_instead_of_up_branch.py62
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0013_recipe_parse_progress_fields.py24
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0014_allow_empty_buildname.py19
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0015_layer_local_source_dir.py19
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py1019
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/orm/tests.py180
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/README28
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers.py176
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py218
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py104
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py13
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py178
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py222
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_recipes.py66
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_tasks.py65
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_js_unit_tests.py8
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py215
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_most_recent_builds_states.py211
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py3
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_project_page.py113
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_config_page.py231
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_page.py2
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_sample.py2
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_task_page.py76
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_toastertable_ui.py160
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/README14
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/__init__.py0
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/buildtest.py134
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/test_core_image_min.py396
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/db/__init__.py0
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/db/test_db.py55
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/tests/functional/README0
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/api.py831
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/buildtables.py606
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/fixtures/toastergui-unittest-data.xml145
-rwxr-xr-ximport-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap-responsive.min.css9
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.css6760
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.css.map1
-rwxr-xr-ximport-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css13
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css.map1
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap3-transition.css238
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/default.css599
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.eotbin20290 -> 20127 bytes
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.svg487
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.ttfbin41236 -> 45404 bytes
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woffbin23292 -> 23424 bytes
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woff2bin0 -> 18028 bytes
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html38
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/img/glyphicons-halflings-white.pngbin8777 -> 0 bytes
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/img/glyphicons-halflings.pngbin12799 -> 0 bytes
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.js2363
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.min.js11
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/customrecipe.js36
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/importlayer.js219
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/jsrender.min.js4
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerBtn.js4
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js16
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerdetails.js218
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js282
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/mrbsection.js180
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js99
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projectpage.js232
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projecttopbar.js11
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/table.js191
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/tests/test.js16
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.js1551
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tablefilter.py2
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py253
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/base.html97
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html47
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuildpage.html283
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html44
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html26
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top.html121
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/bpackage.html108
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builddashboard.html379
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildinfo-toastertable.html25
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html64
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builds-toastertable.html8
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildtime.html4
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configuration.html71
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configvars.html150
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customise_btn.html6
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customrecipe.html235
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_pagination_bottom.html22
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_search_header.html78
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_sorted_header.html8
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/dirinfo.html38
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html67
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/filtersnippet.html93
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/generic-toastertable-page.html2
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/importlayer.html290
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing.html23
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing_not_managed.html4
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layer_btn.html12
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layerdetails.html549
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/machine_btn.html10
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/mrb_section.html404
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage.html15
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html68
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newproject.html53
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html16
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_detail.html8
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_detail_base.html62
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html20
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html8
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html12
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/project.html118
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html67
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds.html4
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectconf.html1965
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projects-toastertable.html58
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projecttopbar.html85
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe.html135
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_btn.html13
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_packages.html38
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipedetails.html154
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipes.html113
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html8
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html44
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html46
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/target.html131
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/task.html175
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/tasks.html143
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html32
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-simple.html94
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable.html122
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/unavailable_artifact.html10
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/field_values_filter.py18
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/projecttags.py30
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tests.py166
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/typeaheads.py1
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/urls.py81
-rwxr-xr-ximport-layers/yocto-poky/bitbake/lib/toaster/toastergui/views.py1519
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastergui/widgets.py312
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/builddelete.py2
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/buildslist.py2
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/get-dburl.py9
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/perf.py6
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings.py78
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings_test.py41
-rw-r--r--import-layers/yocto-poky/bitbake/lib/toaster/toastermain/urls.py4
172 files changed, 22813 insertions, 7627 deletions
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcollector/admin.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcollector/admin.py
index c1f85d73d..1f2e07f50 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/bldcollector/admin.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcollector/admin.py
@@ -1,33 +1,33 @@
from django.contrib import admin
-from django.contrib.admin.filters import RelatedFieldListFilter
-from orm.models import BitbakeVersion, Release, LayerSource, ToasterSetting
-from django.forms.widgets import Textarea
+from orm.models import BitbakeVersion, Release, ToasterSetting, Layer_Version
from django import forms
import django.db.models as models
-from django.contrib.admin import widgets, helpers
-
-class LayerSourceAdmin(admin.ModelAdmin):
- pass
class BitbakeVersionAdmin(admin.ModelAdmin):
- # we override the formfield for db URLField because of broken URL validation
+ # we override the formfield for db URLField
+ # because of broken URL validation
def formfield_for_dbfield(self, db_field, **kwargs):
if isinstance(db_field, models.fields.URLField):
return forms.fields.CharField()
- return super(BitbakeVersionAdmin, self).formfield_for_dbfield(db_field, **kwargs)
-
+ return super(BitbakeVersionAdmin, self).formfield_for_dbfield(
+ db_field, **kwargs)
class ReleaseAdmin(admin.ModelAdmin):
pass
+
class ToasterSettingAdmin(admin.ModelAdmin):
pass
-admin.site.register(LayerSource, LayerSourceAdmin)
+
+class LayerVersionsAdmin(admin.ModelAdmin):
+ pass
+
+admin.site.register(Layer_Version, LayerVersionsAdmin)
admin.site.register(BitbakeVersion, BitbakeVersionAdmin)
admin.site.register(Release, ReleaseAdmin)
admin.site.register(ToasterSetting, ToasterSettingAdmin)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/bbcontroller.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/bbcontroller.py
index d09ac1787..912f67bf8 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/bbcontroller.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/bbcontroller.py
@@ -30,7 +30,6 @@ from bldcontrol.models import BuildEnvironment, BRLayer, BRVariable, BRTarget, B
# load Bitbake components
path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
sys.path.insert(0, path)
-import bb.server.xmlrpc
class BitbakeController(object):
""" This is the basic class that controlls a bitbake server.
@@ -38,6 +37,7 @@ class BitbakeController(object):
"""
def __init__(self, be):
+ import bb.server.xmlrpc
self.connection = bb.server.xmlrpc._create_server(be.bbaddress,
int(be.bbport))[0]
@@ -79,7 +79,7 @@ def getBuildEnvironmentController(**kwargs):
The return object MUST always be a BuildEnvironmentController.
"""
- from localhostbecontroller import LocalhostBEController
+ from bldcontrol.localhostbecontroller import LocalhostBEController
be = BuildEnvironment.objects.filter(Q(**kwargs))[0]
if be.betype == BuildEnvironment.TYPE_LOCAL:
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
index 7def1f3a1..e5f7c988c 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
@@ -32,7 +32,7 @@ import subprocess
from toastermain import settings
-from bbcontroller import BuildEnvironmentController, ShellCmdException, BuildSetupException, BitbakeController
+from bldcontrol.bbcontroller import BuildEnvironmentController, ShellCmdException, BuildSetupException, BitbakeController
import logging
logger = logging.getLogger("toaster")
@@ -66,16 +66,16 @@ class LocalhostBEController(BuildEnvironmentController):
err = "command: %s \n%s" % (command, out)
else:
err = "command: %s \n%s" % (command, err)
- logger.warn("localhostbecontroller: shellcmd error %s" % err)
+ logger.warning("localhostbecontroller: shellcmd error %s" % err)
raise ShellCmdException(err)
else:
logger.debug("localhostbecontroller: shellcmd success")
- return out
+ return out.decode('utf-8')
def getGitCloneDirectory(self, url, branch):
"""Construct unique clone directory name out of url and branch."""
if branch != "HEAD":
- return "_toaster_clones/_%s_%s" % (re.sub('[:/@%]', '_', url), branch)
+ return "_toaster_clones/_%s_%s" % (re.sub('[:/@+%]', '_', url), branch)
# word of attention; this is a localhost-specific issue; only on the localhost we expect to have "HEAD" releases
# which _ALWAYS_ means the current poky checkout
@@ -89,19 +89,34 @@ class LocalhostBEController(BuildEnvironmentController):
""" a word of attention: by convention, the first layer for any build will be poky! """
assert self.be.sourcedir is not None
+
+ layerlist = []
+ nongitlayerlist = []
+
# set layers in the layersource
# 1. get a list of repos with branches, and map dirpaths for each layer
gitrepos = {}
- gitrepos[(bitbake.giturl, bitbake.commit)] = []
- gitrepos[(bitbake.giturl, bitbake.commit)].append( ("bitbake", bitbake.dirpath) )
+ # if we're using a remotely fetched version of bitbake add its git
+ # details to the list of repos to clone
+ if bitbake.giturl and bitbake.commit:
+ gitrepos[(bitbake.giturl, bitbake.commit)] = []
+ gitrepos[(bitbake.giturl, bitbake.commit)].append(
+ ("bitbake", bitbake.dirpath))
for layer in layers:
# We don't need to git clone the layer for the CustomImageRecipe
# as it's generated by us layer on if needed
if CustomImageRecipe.LAYER_NAME in layer.name:
continue
+
+ # If we have local layers then we don't need clone them
+ # For local layers giturl will be empty
+ if not layer.giturl:
+ nongitlayerlist.append(layer.layer_version.layer.local_source_dir)
+ continue
+
if not (layer.giturl, layer.commit) in gitrepos:
gitrepos[(layer.giturl, layer.commit)] = []
gitrepos[(layer.giturl, layer.commit)].append( (layer.name, layer.dirpath) )
@@ -131,19 +146,22 @@ class LocalhostBEController(BuildEnvironmentController):
logger.info("Using pre-checked out source for layer %s", cached_layers)
- layerlist = []
-
-
# 3. checkout the repositories
for giturl, commit in gitrepos.keys():
localdirname = os.path.join(self.be.sourcedir, self.getGitCloneDirectory(giturl, commit))
logger.debug("localhostbecontroller: giturl %s:%s checking out in current directory %s" % (giturl, commit, localdirname))
- # make sure our directory is a git repository
+ # see if our directory is a git repository
if os.path.exists(localdirname):
- localremotes = self._shellcmd("git remote -v", localdirname)
- if not giturl in localremotes:
- raise BuildSetupException("Existing git repository at %s, but with different remotes ('%s', expected '%s'). Toaster will not continue out of fear of damaging something." % (localdirname, ", ".join(localremotes.split("\n")), giturl))
+ try:
+ localremotes = self._shellcmd("git remote -v",
+ localdirname)
+ if not giturl in localremotes and commit != 'HEAD':
+ raise BuildSetupException("Existing git repository at %s, but with different remotes ('%s', expected '%s'). Toaster will not continue out of fear of damaging something." % (localdirname, ", ".join(localremotes.split("\n")), giturl))
+ except ShellCmdException:
+ # our localdirname might not be a git repository
+ #- that's fine
+ pass
else:
if giturl in cached_layers:
logger.debug("localhostbecontroller git-copying %s to %s" % (cached_layers[giturl], localdirname))
@@ -245,6 +263,7 @@ class LocalhostBEController(BuildEnvironmentController):
layerlist.append(layerpath)
self.islayerset = True
+ layerlist.extend(nongitlayerlist)
return layerlist
def readServerLogFile(self):
@@ -287,7 +306,7 @@ class LocalhostBEController(BuildEnvironmentController):
# run bitbake server from the clone
bitbake = os.path.join(self.pokydirname, 'bitbake', 'bin', 'bitbake')
- self._shellcmd('bash -c \"source %s %s; BITBAKE_UI="" %s --read %s '
+ self._shellcmd('bash -c \"source %s %s; BITBAKE_UI="knotty" %s --read %s '
'--server-only -t xmlrpc -B 0.0.0.0:0\"' % (oe_init,
builddir, bitbake, confpath), self.be.sourcedir)
@@ -324,7 +343,7 @@ class LocalhostBEController(BuildEnvironmentController):
'bitbake')
self._shellcmd(['bash -c \"(TOASTER_BRBE="%s" BBSERVER="0.0.0.0:-1" '
'%s %s -u toasterui --token="" >>%s 2>&1;'
- 'BITBAKE_UI="" BBSERVER=0.0.0.0:-1 %s -m)&\"' \
+ 'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:-1 %s -m)&\"' \
% (brbe, local_bitbake, bbtargets, log, bitbake)],
builddir, nowait=True)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
index 5e70437b2..2ed994f61 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
@@ -1,10 +1,15 @@
from django.core.management.base import NoArgsCommand, CommandError
from django.db import transaction
+
+from django.core.management import call_command
from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException
from bldcontrol.models import BuildRequest, BuildEnvironment, BRError
-from orm.models import ToasterSetting, Build
+from orm.models import ToasterSetting, Build, Layer
+
import os
import traceback
+import warnings
+
def DN(path):
if path is None:
@@ -21,39 +26,6 @@ class Command(NoArgsCommand):
super(Command, self).__init__(*args, **kwargs)
self.guesspath = DN(DN(DN(DN(DN(DN(DN(__file__)))))))
- def _find_first_path_for_file(self, startdirectory, filename, level=0):
- if level < 0:
- return None
- dirs = []
- for i in os.listdir(startdirectory):
- j = os.path.join(startdirectory, i)
- if os.path.isfile(j):
- if i == filename:
- return startdirectory
- elif os.path.isdir(j):
- dirs.append(j)
- for j in dirs:
- ret = self._find_first_path_for_file(j, filename, level - 1)
- if ret is not None:
- return ret
- return None
-
- def _recursive_list_directories(self, startdirectory, level=0):
- if level < 0:
- return []
- dirs = []
- try:
- for i in os.listdir(startdirectory):
- j = os.path.join(startdirectory, i)
- if os.path.isdir(j):
- dirs.append(j)
- except OSError:
- pass
- for j in dirs:
- dirs = dirs + self._recursive_list_directories(j, level - 1)
- return dirs
-
-
def _verify_build_environment(self):
# provide a local build env. This will be extended later to include non local
if BuildEnvironment.objects.count() == 0:
@@ -70,11 +42,10 @@ class Command(NoArgsCommand):
return True
if len(be.sourcedir) == 0:
- print "\n -- Validation: The layers checkout directory must be set."
is_changed = _update_sourcedir()
if not be.sourcedir.startswith("/"):
- print "\n -- Validation: The layers checkout directory must be set to an absolute path."
+ print("\n -- Validation: The layers checkout directory must be set to an absolute path.")
is_changed = _update_sourcedir()
if is_changed:
@@ -87,38 +58,67 @@ class Command(NoArgsCommand):
return True
if len(be.builddir) == 0:
- print "\n -- Validation: The build directory must be set."
is_changed = _update_builddir()
if not be.builddir.startswith("/"):
- print "\n -- Validation: The build directory must to be set to an absolute path."
+ print("\n -- Validation: The build directory must to be set to an absolute path.")
is_changed = _update_builddir()
-
if is_changed:
- print "\nBuild configuration saved"
+ print("\nBuild configuration saved")
be.save()
return True
-
if be.needs_import:
try:
- config_file = os.environ.get('TOASTER_CONF')
- print "\nImporting file: %s" % config_file
- from loadconf import Command as LoadConfigCommand
+ print("Loading default settings")
+ call_command("loaddata", "settings")
+ template_conf = os.environ.get("TEMPLATECONF", "")
+
+ if "poky" in template_conf:
+ print("Loading poky configuration")
+ call_command("loaddata", "poky")
+ else:
+ print("Loading OE-Core configuration")
+ call_command("loaddata", "oe-core")
+ if template_conf:
+ oe_core_path = os.path.realpath(
+ template_conf +
+ "/../")
+ else:
+ print("TEMPLATECONF not found. You may have to"
+ " manually configure layer paths")
+ oe_core_path = input("Please enter the path of"
+ " your openembedded-core "
+ "layer: ")
+ # Update the layer instances of openemebedded-core
+ for layer in Layer.objects.filter(
+ name="openembedded-core",
+ local_source_dir="OE-CORE-LAYER-DIR"):
+ layer.local_path = oe_core_path
+ layer.save()
+
+ # Import the custom fixture if it's present
+ with warnings.catch_warnings():
+ warnings.filterwarnings(
+ action="ignore",
+ message="^.*No fixture named.*$")
+ print("Importing custom settings if present")
+ call_command("loaddata", "custom")
- LoadConfigCommand()._import_layer_config(config_file)
# we run lsupdates after config update
- print "\nLayer configuration imported. Updating information from the layer sources, please wait.\nYou can re-update any time later by running bitbake/lib/toaster/manage.py lsupdates"
- from django.core.management import call_command
+ print("\nFetching information from the layer index, "
+ "please wait.\nYou can re-update any time later "
+ "by running bitbake/lib/toaster/manage.py "
+ "lsupdates\n")
call_command("lsupdates")
# we don't look for any other config files
return is_changed
except Exception as e:
- print "Failure while trying to import the toaster config file %s: %s" %\
- (config_file, e)
- traceback.print_exc(e)
+ print("Failure while trying to setup toaster: %s"
+ % e)
+ traceback.print_exc()
return is_changed
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/loadconf.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/loadconf.py
deleted file mode 100644
index 5022b5940..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/loadconf.py
+++ /dev/null
@@ -1,183 +0,0 @@
-from django.core.management.base import BaseCommand, CommandError
-from orm.models import LayerSource, ToasterSetting, Branch, Layer, Layer_Version
-from orm.models import BitbakeVersion, Release, ReleaseDefaultLayer, ReleaseLayerSourcePriority
-from django.db import IntegrityError
-import os
-
-from checksettings import DN
-
-import logging
-logger = logging.getLogger("toaster")
-
-def _reduce_canon_path(path):
- components = []
- for c in path.split("/"):
- if c == "..":
- del components[-1]
- elif c == ".":
- pass
- else:
- components.append(c)
- if len(components) < 2:
- components.append('')
- return "/".join(components)
-
-def _get_id_for_sourcetype(s):
- for i in LayerSource.SOURCE_TYPE:
- if s == i[1]:
- return i[0]
- raise Exception("Could not find definition for sourcetype '%s'. Valid source types are %s" % (str(s), ', '.join(map(lambda x: "'%s'" % x[1], LayerSource.SOURCE_TYPE ))))
-
-class Command(BaseCommand):
- help = "Loads a toasterconf.json file in the database"
- args = "filepath"
-
-
-
- def _import_layer_config(self, filepath):
- if not os.path.exists(filepath) or not os.path.isfile(filepath):
- raise Exception("Failed to find toaster config file %s ." % filepath)
-
- import json
- data = json.loads(open(filepath, "r").read())
-
- # verify config file validity before updating settings
- for i in ['bitbake', 'releases', 'defaultrelease', 'config', 'layersources']:
- assert i in data
-
- def _read_git_url_from_local_repository(address):
- url = None
- # we detect the remote name at runtime
- import subprocess
- (remote, remote_name) = address.split(":", 1)
- cmd = subprocess.Popen("git remote -v", shell=True, cwd = os.path.dirname(filepath), stdout=subprocess.PIPE, stderr = subprocess.PIPE)
- (out,err) = cmd.communicate()
- if cmd.returncode != 0:
- logging.warning("Error while importing layer vcs_url: git error: %s" % err)
- for line in out.split("\n"):
- try:
- (name, path) = line.split("\t", 1)
- if name == remote_name:
- url = path.split(" ")[0]
- break
- except ValueError:
- pass
- if url == None:
- logging.warning("Error while looking for remote \"%s\" in \"%s\"" % (remote_name, out))
- return url
-
-
- # import bitbake data
- for bvi in data['bitbake']:
- bvo, created = BitbakeVersion.objects.get_or_create(name=bvi['name'])
- if bvi['giturl'].startswith("remote:"):
- bvo.giturl = _read_git_url_from_local_repository(bvi['giturl'])
- if bvo.giturl is None:
- logger.error("The toaster config file references the local git repo, but Toaster cannot detect it.\nYour local configuration for bitbake version %s is invalid. Make sure that the toasterconf.json file is correct." % bvi['name'])
-
- if bvo.giturl is None:
- bvo.giturl = bvi['giturl']
- bvo.branch = bvi['branch']
- bvo.dirpath = bvi['dirpath']
- bvo.save()
-
- # set the layer sources
- for lsi in data['layersources']:
- assert 'sourcetype' in lsi
- assert 'apiurl' in lsi
- assert 'name' in lsi
- assert 'branches' in lsi
-
-
- if _get_id_for_sourcetype(lsi['sourcetype']) == LayerSource.TYPE_LAYERINDEX or lsi['apiurl'].startswith("/"):
- apiurl = lsi['apiurl']
- else:
- apiurl = _reduce_canon_path(os.path.join(DN(os.path.abspath(filepath)), lsi['apiurl']))
-
- assert ((_get_id_for_sourcetype(lsi['sourcetype']) == LayerSource.TYPE_LAYERINDEX) or apiurl.startswith("/")), (lsi['sourcetype'],apiurl)
-
- try:
- ls, created = LayerSource.objects.get_or_create(sourcetype = _get_id_for_sourcetype(lsi['sourcetype']), apiurl = apiurl)
- ls.name = lsi['name']
- ls.save()
- except IntegrityError as e:
- logger.warning("IntegrityError %s \nWhile setting name %s for layer source %s " % (e, lsi['name'], ls))
-
-
- layerbranches = []
- for branchname in lsi['branches']:
- bo, created = Branch.objects.get_or_create(layer_source = ls, name = branchname)
- layerbranches.append(bo)
-
- if 'layers' in lsi:
- for layerinfo in lsi['layers']:
- lo, created = Layer.objects.get_or_create(layer_source = ls, name = layerinfo['name'])
- if layerinfo['local_path'].startswith("/"):
- lo.local_path = layerinfo['local_path']
- else:
- lo.local_path = _reduce_canon_path(os.path.join(ls.apiurl, layerinfo['local_path']))
-
- if not os.path.exists(lo.local_path):
- logger.error("Local layer path %s must exists. Are you trying to import a layer that does not exist ? Check your local toasterconf.json" % lo.local_path)
-
- if layerinfo['vcs_url'].startswith("remote:"):
- lo.vcs_url = _read_git_url_from_local_repository(layerinfo['vcs_url'])
- if lo.vcs_url is None:
- logger.error("The toaster config file references the local git repo, but Toaster cannot detect it.\nYour local configuration for layer %s is invalid. Make sure that the toasterconf.json file is correct." % layerinfo['name'])
-
- if lo.vcs_url is None:
- lo.vcs_url = layerinfo['vcs_url']
-
- if 'layer_index_url' in layerinfo:
- lo.layer_index_url = layerinfo['layer_index_url']
- lo.save()
-
- for branch in layerbranches:
- lvo, created = Layer_Version.objects.get_or_create(layer_source = ls,
- up_branch = branch,
- commit = branch.name,
- layer = lo)
- lvo.dirpath = layerinfo['dirpath']
- lvo.save()
- # set releases
- for ri in data['releases']:
- bvo = BitbakeVersion.objects.get(name = ri['bitbake'])
- assert bvo is not None
-
- ro, created = Release.objects.get_or_create(name = ri['name'], bitbake_version = bvo, branch_name = ri['branch'])
- ro.description = ri['description']
- ro.helptext = ri['helptext']
- ro.save()
-
- # save layer source priority for release
- for ls_name in ri['layersourcepriority'].keys():
- rlspo, created = ReleaseLayerSourcePriority.objects.get_or_create(release = ro, layer_source = LayerSource.objects.get(name=ls_name))
- rlspo.priority = ri['layersourcepriority'][ls_name]
- rlspo.save()
-
- for dli in ri['defaultlayers']:
- # find layers with the same name
- ReleaseDefaultLayer.objects.get_or_create( release = ro, layer_name = dli)
-
- # set default release
- if ToasterSetting.objects.filter(name = "DEFAULT_RELEASE").count() > 0:
- ToasterSetting.objects.filter(name = "DEFAULT_RELEASE").update(value = data['defaultrelease'])
- else:
- ToasterSetting.objects.create(name = "DEFAULT_RELEASE", value = data['defaultrelease'])
-
- # set default config variables
- for configname in data['config']:
- if ToasterSetting.objects.filter(name = "DEFCONF_" + configname).count() > 0:
- ToasterSetting.objects.filter(name = "DEFCONF_" + configname).update(value = data['config'][configname])
- else:
- ToasterSetting.objects.create(name = "DEFCONF_" + configname, value = data['config'][configname])
-
-
- def handle(self, *args, **options):
- if len(args) == 0:
- raise CommandError("Need a path to the toasterconf.json file")
- filepath = args[0]
- self._import_layer_config(filepath)
-
-
-
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
index 27289be5f..7f7a5a955 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
@@ -1,31 +1,27 @@
-from django.core.management.base import NoArgsCommand, CommandError
+from django.core.management.base import NoArgsCommand
from django.db import transaction
from django.db.models import Q
from bldcontrol.bbcontroller import getBuildEnvironmentController
-from bldcontrol.bbcontroller import ShellCmdException, BuildSetupException
from bldcontrol.models import BuildRequest, BuildEnvironment
from bldcontrol.models import BRError, BRVariable
-from orm.models import Build, ToasterSetting, LogMessage, Target
+from orm.models import Build, LogMessage, Target
-import os
import logging
-import time
-import sys
import traceback
+import signal
logger = logging.getLogger("toaster")
class Command(NoArgsCommand):
- args = ""
- help = "Schedules and executes build requests as possible."
- "Does not return (interrupt with Ctrl-C)"
-
+ args = ""
+ help = "Schedules and executes build requests as possible. "\
+ "Does not return (interrupt with Ctrl-C)"
@transaction.atomic
def _selectBuildEnvironment(self):
- bec = getBuildEnvironmentController(lock = BuildEnvironment.LOCK_FREE)
+ bec = getBuildEnvironmentController(lock=BuildEnvironment.LOCK_FREE)
bec.be.lock = BuildEnvironment.LOCK_LOCK
bec.be.save()
return bec
@@ -54,8 +50,8 @@ class Command(NoArgsCommand):
logger.debug("runbuilds: No build env")
return
- logger.debug("runbuilds: starting build %s, environment %s" % \
- (str(br).decode('utf-8'), bec.be))
+ logger.info("runbuilds: starting build %s, environment %s" % \
+ (br, bec.be))
# let the build request know where it is being executed
br.environment = bec.be
@@ -68,24 +64,22 @@ class Command(NoArgsCommand):
except Exception as e:
logger.error("runbuilds: Error launching build %s" % e)
- traceback.print_exc(e)
+ traceback.print_exc()
if "[Errno 111] Connection refused" in str(e):
# Connection refused, read toaster_server.out
errmsg = bec.readServerLogFile()
else:
errmsg = str(e)
- BRError.objects.create(req = br,
- errtype = str(type(e)),
- errmsg = errmsg,
- traceback = traceback.format_exc(e))
+ BRError.objects.create(req=br, errtype=str(type(e)), errmsg=errmsg,
+ traceback=traceback.format_exc())
br.state = BuildRequest.REQ_FAILED
br.save()
bec.be.lock = BuildEnvironment.LOCK_FREE
bec.be.save()
def archive(self):
- for br in BuildRequest.objects.filter(state = BuildRequest.REQ_ARCHIVE):
+ for br in BuildRequest.objects.filter(state=BuildRequest.REQ_ARCHIVE):
if br.build == None:
br.state = BuildRequest.REQ_FAILED
else:
@@ -102,14 +96,13 @@ class Command(NoArgsCommand):
BuildRequest.REQ_COMPLETED,
BuildRequest.REQ_CANCELLING]) &
Q(lock=BuildEnvironment.LOCK_LOCK) &
- Q(updated__lt=timezone.now() - timedelta(seconds = 30))
+ Q(updated__lt=timezone.now() - timedelta(seconds=30))
).update(lock=BuildEnvironment.LOCK_FREE)
# update all Builds that were in progress and failed to start
- for br in BuildRequest.objects.filter(
- state=BuildRequest.REQ_FAILED,
- build__outcome=Build.IN_PROGRESS):
+ for br in BuildRequest.objects.filter(state=BuildRequest.REQ_FAILED,
+ build__outcome=Build.IN_PROGRESS):
# transpose the launch errors in ToasterExceptions
br.build.outcome = Build.FAILED
for brerror in br.brerror_set.all():
@@ -126,7 +119,7 @@ class Command(NoArgsCommand):
# update all BuildRequests without a build created
- for br in BuildRequest.objects.filter(build = None):
+ for br in BuildRequest.objects.filter(build=None):
br.build = Build.objects.create(project=br.project,
completed_on=br.updated,
started_on=br.created)
@@ -151,29 +144,34 @@ class Command(NoArgsCommand):
# Make sure the LOCK is removed for builds which have been fully
# cancelled
- for br in BuildRequest.objects.filter(
- Q(build__outcome=Build.CANCELLED) &
- Q(state=BuildRequest.REQ_CANCELLING) &
- ~Q(environment=None)):
+ for br in BuildRequest.objects.filter(\
+ Q(build__outcome=Build.CANCELLED) &
+ Q(state=BuildRequest.REQ_CANCELLING) &
+ ~Q(environment=None)):
br.environment.lock = BuildEnvironment.LOCK_FREE
br.environment.save()
+ def runbuild(self):
+ try:
+ self.cleanup()
+ except Exception as e:
+ logger.warn("runbuilds: cleanup exception %s" % str(e))
- def handle_noargs(self, **options):
- while True:
- try:
- self.cleanup()
- except Exception as e:
- logger.warn("runbuilds: cleanup exception %s" % str(e))
+ try:
+ self.archive()
+ except Exception as e:
+ logger.warn("runbuilds: archive exception %s" % str(e))
- try:
- self.archive()
- except Exception as e:
- logger.warn("runbuilds: archive exception %s" % str(e))
+ try:
+ self.schedule()
+ except Exception as e:
+ logger.warn("runbuilds: schedule exception %s" % str(e))
- try:
- self.schedule()
- except Exception as e:
- logger.warn("runbuilds: schedule exception %s" % str(e))
+ def handle_noargs(self, **options):
+ self.runbuild()
+
+ signal.signal(signal.SIGUSR1, lambda sig, frame: None)
- time.sleep(1)
+ while True:
+ signal.pause()
+ self.runbuild()
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0004_auto_20160523_1446.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0004_auto_20160523_1446.py
new file mode 100644
index 000000000..3d9062954
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0004_auto_20160523_1446.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bldcontrol', '0003_add_cancelling_state'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='buildenvironment',
+ name='bbstate',
+ field=models.IntegerField(default=0, choices=[(0, 'stopped'), (1, 'started')]),
+ ),
+ migrations.AlterField(
+ model_name='buildenvironment',
+ name='betype',
+ field=models.IntegerField(choices=[(0, 'local')]),
+ ),
+ migrations.AlterField(
+ model_name='buildenvironment',
+ name='lock',
+ field=models.IntegerField(default=0, choices=[(0, 'free'), (1, 'lock'), (2, 'running')]),
+ ),
+ migrations.AlterField(
+ model_name='buildrequest',
+ name='state',
+ field=models.IntegerField(default=0, choices=[(0, 'created'), (1, 'queued'), (2, 'in progress'), (3, 'completed'), (4, 'failed'), (5, 'deleted'), (6, 'cancelling'), (7, 'archive')]),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0005_reorder_buildrequest_states.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0005_reorder_buildrequest_states.py
new file mode 100644
index 000000000..4bb951776
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0005_reorder_buildrequest_states.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bldcontrol', '0004_auto_20160523_1446'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='buildrequest',
+ name='state',
+ field=models.IntegerField(choices=[(0, 'created'), (1, 'queued'), (2, 'in progress'), (3, 'failed'), (4, 'deleted'), (5, 'cancelling'), (6, 'completed'), (7, 'archive')], default=0),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0006_brlayer_local_source_dir.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0006_brlayer_local_source_dir.py
new file mode 100644
index 000000000..2460002f0
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0006_brlayer_local_source_dir.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bldcontrol', '0005_reorder_buildrequest_states'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='brlayer',
+ name='local_source_dir',
+ field=models.CharField(max_length=254, null=True),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0007_brlayers_optional_gitinfo.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0007_brlayers_optional_gitinfo.py
new file mode 100644
index 000000000..4be42a4cf
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/migrations/0007_brlayers_optional_gitinfo.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bldcontrol', '0006_brlayer_local_source_dir'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='brlayer',
+ name='commit',
+ field=models.CharField(max_length=254, null=True),
+ ),
+ migrations.AlterField(
+ model_name='brlayer',
+ name='dirpath',
+ field=models.CharField(max_length=254, null=True),
+ ),
+ migrations.AlterField(
+ model_name='brlayer',
+ name='giturl',
+ field=models.CharField(max_length=254, null=True),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/models.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/models.py
index cb49a58c4..409614b9e 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/models.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/models.py
@@ -1,7 +1,7 @@
from __future__ import unicode_literals
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
-from django.utils.encoding import force_bytes
+from django.utils.encoding import force_text
from orm.models import Project, ProjectLayer, ProjectVariable, ProjectTarget, Build, Layer_Version
import logging
@@ -63,20 +63,20 @@ class BuildRequest(models.Model):
REQ_CREATED = 0
REQ_QUEUED = 1
REQ_INPROGRESS = 2
- REQ_COMPLETED = 3
- REQ_FAILED = 4
- REQ_DELETED = 5
- REQ_CANCELLING = 6
+ REQ_FAILED = 3
+ REQ_DELETED = 4
+ REQ_CANCELLING = 5
+ REQ_COMPLETED = 6
REQ_ARCHIVE = 7
REQUEST_STATE = (
(REQ_CREATED, "created"),
(REQ_QUEUED, "queued"),
(REQ_INPROGRESS, "in progress"),
- (REQ_COMPLETED, "completed"),
(REQ_FAILED, "failed"),
(REQ_DELETED, "deleted"),
(REQ_CANCELLING, "cancelling"),
+ (REQ_COMPLETED, "completed"),
(REQ_ARCHIVE, "archive"),
)
@@ -91,18 +91,18 @@ class BuildRequest(models.Model):
def __init__(self, *args, **kwargs):
super(BuildRequest, self).__init__(*args, **kwargs)
- # Save the old state incase it's about to be modified
+ # Save the old state in case it's about to be modified
self.old_state = self.state
def save(self, *args, **kwargs):
# Check that the state we're trying to set is not going backwards
# e.g. from REQ_FAILED to REQ_INPROGRESS
if self.old_state != self.state and self.old_state > self.state:
- logger.warn("Invalid state change requested: "
- "Cannot go from %s to %s - ignoring request" %
- (BuildRequest.REQUEST_STATE[self.old_state][1],
- BuildRequest.REQUEST_STATE[self.state][1])
- )
+ logger.warning("Invalid state change requested: "
+ "Cannot go from %s to %s - ignoring request" %
+ (BuildRequest.REQUEST_STATE[self.old_state][1],
+ BuildRequest.REQUEST_STATE[self.state][1])
+ )
# Set property back to the old value
self.state = self.old_state
return
@@ -121,17 +121,19 @@ class BuildRequest(models.Model):
return self.brvariable_set.get(name="MACHINE").value
def __str__(self):
- return force_bytes('%s %s' % (self.project, self.get_state_display()))
+ return force_text('%s %s' % (self.project, self.get_state_display()))
# These tables specify the settings for running an actual build.
# They MUST be kept in sync with the tables in orm.models.Project*
+
class BRLayer(models.Model):
- req = models.ForeignKey(BuildRequest)
- name = models.CharField(max_length = 100)
- giturl = models.CharField(max_length = 254)
- commit = models.CharField(max_length = 254)
- dirpath = models.CharField(max_length = 254)
+ req = models.ForeignKey(BuildRequest)
+ name = models.CharField(max_length=100)
+ giturl = models.CharField(max_length=254, null=True)
+ local_source_dir = models.CharField(max_length=254, null=True)
+ commit = models.CharField(max_length=254, null=True)
+ dirpath = models.CharField(max_length=254, null=True)
layer_version = models.ForeignKey(Layer_Version, null=True)
class BRBitbake(models.Model):
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/tests.py b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/tests.py
index f20cc7d4b..475ac0a16 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/tests.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/bldcontrol/tests.py
@@ -53,7 +53,7 @@ class BEControllerTests(object):
# setting layers, skip any layer info
bc.setLayers(BITBAKE_LAYER, POKY_LAYERS)
except NotImplementedError:
- print "Test skipped due to command not implemented yet"
+ print("Test skipped due to command not implemented yet")
return True
# We are ok with the exception as we're handling the git already exists
except BuildSetupException:
@@ -79,7 +79,7 @@ class BEControllerTests(object):
# setting layers, skip any layer info
layerSet = bc.setLayers(BITBAKE_LAYER, POKY_LAYERS)
except NotImplementedError:
- print "Test skipped due to command not implemented yet"
+ print("Test skipped due to command not implemented yet")
return True
# We are ok with the exception as we're handling the git already exists
except BuildSetupException:
@@ -139,22 +139,3 @@ class RunBuildsCommandTests(TestCase):
self.assertTrue(br.state == BuildRequest.REQ_INPROGRESS, "Request is not updated")
# no more selections possible here
self.assertRaises(IndexError, command._selectBuildRequest)
-
-
-class UtilityTests(TestCase):
- def test_reduce_path(self):
- from bldcontrol.management.commands.loadconf import _reduce_canon_path, _get_id_for_sourcetype
-
- self.assertTrue( _reduce_canon_path("/") == "/")
- self.assertTrue( _reduce_canon_path("/home/..") == "/")
- self.assertTrue( _reduce_canon_path("/home/../ana") == "/ana")
- self.assertTrue( _reduce_canon_path("/home/../ana/..") == "/")
- self.assertTrue( _reduce_canon_path("/home/ana/mihai/../maria") == "/home/ana/maria")
-
- def test_get_id_for_sorucetype(self):
- from bldcontrol.management.commands.loadconf import _reduce_canon_path, _get_id_for_sourcetype
- self.assertTrue( _get_id_for_sourcetype("layerindex") == 1)
- self.assertTrue( _get_id_for_sourcetype("local") == 0)
- self.assertTrue( _get_id_for_sourcetype("imported") == 2)
- with self.assertRaises(Exception):
- _get_id_for_sourcetype("unknown")
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/config.py b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/config.py
index 40d45f3b7..87b427cc3 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/config.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/config.py
@@ -74,7 +74,7 @@ BACKLOGFILE = os.path.join(os.path.dirname(__file__), "backlog.txt")
# task states
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
- reverse = dict((value, key) for key, value in enums.iteritems())
+ reverse = dict((value, key) for key, value in enums.items())
enums['reverse_mapping'] = reverse
return type('Enum', (), enums)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/log/.create b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/log/.create
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/log/.create
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/runner.py b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/runner.py
index bed665196..d01386acf 100755
--- a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/runner.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/runner.py
@@ -146,7 +146,7 @@ def execute_tests(dir_under_test, testname):
except Exception as exc:
import traceback
- config.logger.error("Exception while running test. Tracedump: \n%s", traceback.format_exc(exc))
+ config.logger.error("Exception while running test. Tracedump: \n%s", traceback.format_exc())
finally:
os.chdir(crt_dir)
return len(result.failures)
@@ -211,7 +211,7 @@ def main():
except ShellCmdException as exc:
import traceback
- config.logger.error("Error while setting up testing. Traceback: \n%s", traceback.format_exc(exc))
+ config.logger.error("Error while setting up testing. Traceback: \n%s", traceback.format_exc())
finally:
if need_cleanup and testdir is not None:
clean_up(testdir)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/shellutils.py b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/shellutils.py
index c2012edf8..ce64c0634 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/shellutils.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/shellutils.py
@@ -133,7 +133,7 @@ def run_shell_cmd(command, cwd=None):
err = "command: %s \n%s" % (command, out)
else:
err = "command: %s \n%s" % (command, err)
- config.logger.warn("_shellcmd: error \n%s\n%s", out, err)
+ config.logger.warning("_shellcmd: error \n%s\n%s", out, err)
raise ShellCmdException(err)
else:
#config.logger.debug("localhostbecontroller: shellcmd success\n%s" % out)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/run_toastertests.py b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/run_toastertests.py
index 754636f0f..8ca45a813 100755
--- a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/run_toastertests.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/run_toastertests.py
@@ -74,7 +74,7 @@ def get_tests_from_cfg(suite=None):
try:
tests_from_cfg = eval(config.get('toaster_test_' + target_suite, 'test_cases'))
except:
- print 'Failed to get test cases from cfg file. Make sure the format is correct.'
+ print('Failed to get test cases from cfg file. Make sure the format is correct.')
return None
prefix = 'toaster_automation_test.toaster_cases.test_'
@@ -100,7 +100,7 @@ def main():
testslist = get_tests_from_cfg()
if not testslist:
- print 'Failed to get test cases.'
+ print('Failed to get test cases.')
exit(1)
suite = unittest.TestSuite()
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py
index d8f838aea..1a786fa02 100755
--- a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/toasteruitest/toaster_automation_test.py
@@ -61,7 +61,7 @@ def get_log_root_dir():
break
if number == (max_depth - 1):
- print 'No log dir found. Please check'
+ print('No log dir found. Please check')
raise Exception
return log_root_dir
@@ -152,7 +152,7 @@ def is_list_sequenced(testlist):
return (sorted(list_number) == list_number)
else:
- print 'Unrecognized list type, please check'
+ print('Unrecognized list type, please check')
return False
@@ -201,7 +201,7 @@ def is_list_inverted(testlist):
return (sorted(list_number, reverse = True) == list_number)
else:
- print 'Unrecognized list type, please check'
+ print('Unrecognized list type, please check')
return False
def replace_file_content(filename, item, option):
@@ -361,7 +361,7 @@ class toaster_cases_base(unittest.TestCase):
def setup_browser(self, *browser_path):
self.browser = eval(self.parser.get('toaster_test_' + self.target_suite, 'test_browser'))
- print self.browser
+ print(self.browser)
if self.browser == "firefox":
driver = webdriver.Firefox()
elif self.browser == "chrome":
@@ -370,7 +370,7 @@ class toaster_cases_base(unittest.TestCase):
driver = webdriver.Ie()
else:
driver = None
- print "unrecognized browser type, please check"
+ print("unrecognized browser type, please check")
self.driver = driver
self.driver.implicitly_wait(30)
return self.driver
@@ -440,8 +440,8 @@ class toaster_cases_base(unittest.TestCase):
try:
table_element = self.get_table_element(table_id)
element = table_element.find_element_by_xpath("//*[text()='" + text_string + "']")
- except NoSuchElementException, e:
- print 'no element found'
+ except NoSuchElementException as e:
+ print('no element found')
raise
return element
@@ -454,8 +454,8 @@ class toaster_cases_base(unittest.TestCase):
try:
table_element = self.get_table_element(table_id)
element = table_element.find_element_by_link_text(link_text)
- except NoSuchElementException, e:
- print 'no element found'
+ except NoSuchElementException as e:
+ print('no element found')
raise
return element
@@ -467,8 +467,8 @@ class toaster_cases_base(unittest.TestCase):
try:
table_element = self.get_table_element(table_id)
element_list = table_element.find_elements_by_link_text(link_text)
- except NoSuchElementException, e:
- print 'no element found'
+ except NoSuchElementException as e:
+ print('no element found')
raise
return element_list
@@ -481,8 +481,8 @@ class toaster_cases_base(unittest.TestCase):
table_element = self.get_table_element(table_id)
element = table_element.find_element_by_partial_link_text(link_text)
return element
- except NoSuchElementException, e:
- print 'no element found'
+ except NoSuchElementException as e:
+ print('no element found')
raise
@@ -494,8 +494,8 @@ class toaster_cases_base(unittest.TestCase):
table_element = self.get_table_element(table_id)
element_list = table_element.find_elements_by_partial_link_text(link_text)
return element_list
- except NoSuchElementException, e:
- print 'no element found'
+ except NoSuchElementException as e:
+ print('no element found')
raise
@@ -506,8 +506,8 @@ class toaster_cases_base(unittest.TestCase):
try:
table_element = self.get_table_element(table_id)
element = table_element.find_element_by_xpath(xpath)
- except NoSuchElementException, e:
- print 'no element found'
+ except NoSuchElementException as e:
+ print('no element found')
raise
return element
@@ -519,8 +519,8 @@ class toaster_cases_base(unittest.TestCase):
try:
table_element = self.get_table_element(table_id)
element_list = table_element.find_elements_by_xpath(xpath)
- except NoSuchElementException, e:
- print 'no elements found'
+ except NoSuchElementException as e:
+ print('no elements found')
raise
return element_list
@@ -570,7 +570,7 @@ class toaster_cases_base(unittest.TestCase):
element_xpath = "//*[@id='" + table_id + "']"
try:
element = self.driver.find_element_by_xpath(element_xpath)
- except NoSuchElementException, e:
+ except NoSuchElementException as e:
raise
return element
row = coordinate[0]
@@ -580,7 +580,7 @@ class toaster_cases_base(unittest.TestCase):
element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]"
try:
element = self.driver.find_element_by_xpath(element_xpath)
- except NoSuchElementException, e:
+ except NoSuchElementException as e:
return False
return element
#now we are looking for an element with specified X and Y
@@ -589,7 +589,7 @@ class toaster_cases_base(unittest.TestCase):
element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]/td[" + str(column) + "]"
try:
element = self.driver.find_element_by_xpath(element_xpath)
- except NoSuchElementException, e:
+ except NoSuchElementException as e:
return False
return element
@@ -607,7 +607,7 @@ class toaster_cases_base(unittest.TestCase):
column = column + 1
print("row_content=",row_content)
Lists.extend(row_content)
- print Lists[row-1][0]
+ print(Lists[row-1][0])
row = row + 1
return Lists
@@ -617,7 +617,7 @@ class toaster_cases_base(unittest.TestCase):
def is_text_present (self, patterns):
for pattern in patterns:
if str(pattern) not in self.driver.page_source:
- print 'Text "'+pattern+'" is missing'
+ print('Text "'+pattern+'" is missing')
return False
return True
@@ -625,15 +625,15 @@ class toaster_cases_base(unittest.TestCase):
def is_element_present(self, how, what):
try:
self.driver.find_element(how, what)
- except NoSuchElementException, e:
- print 'Could not find element '+str(what)+' by ' + str(how)
+ except NoSuchElementException as e:
+ print('Could not find element '+str(what)+' by ' + str(how))
return False
return True
def is_alert_present(self):
try: self.driver.switch_to_alert()
- except NoAlertPresentException, e: return False
+ except NoAlertPresentException as e: return False
return True
@@ -658,7 +658,7 @@ class toaster_cases_base(unittest.TestCase):
try:
caseno = int(caseno_str)
except ValueError:
- print "get case number error! please check if func name is test_xxx"
+ print("get case number error! please check if func name is test_xxx")
return False
return caseno
@@ -706,7 +706,7 @@ class toaster_cases(toaster_cases_base):
for key in table_head_dict:
try:
self.driver.find_element_by_link_text(key).click()
- except Exception, e:
+ except Exception as e:
self.log.error("%s cannot be found on page" % key)
raise
column_list = self.get_table_column_text("class", table_head_dict[key])
@@ -736,7 +736,7 @@ class toaster_cases(toaster_cases_base):
patterns = ["minimal", "sato"]
for pattern in patterns:
ori_target_column_texts = self.get_table_column_text("class", "target")
- print ori_target_column_texts
+ print(ori_target_column_texts)
self.driver.find_element_by_id("search").clear()
self.driver.find_element_by_id("search").send_keys(pattern)
self.driver.find_element_by_id("search-button").click()
@@ -771,7 +771,7 @@ class toaster_cases(toaster_cases_base):
temp_element = self.find_element_by_text_in_table('otable', item)
# this is how we find "filter icon" in the same level as temp_element(where "a" means clickable, "i" means icon)
self.assertTrue(temp_element.find_element_by_xpath("..//*/a/i[@class='icon-filter filtered']"))
- except Exception,e:
+ except Exception as e:
self.assertFalse(True, msg=(" %s cannot be found! %s" % (item, e)))
raise
# step 5-6
@@ -812,7 +812,7 @@ class toaster_cases(toaster_cases_base):
self.table_name = 'otable'
# This is how we find the "default" rows-number!
rows_displayed = int(Select(self.driver.find_element_by_css_selector("select.pagesize")).first_selected_option.text)
- print rows_displayed
+ print(rows_displayed)
self.assertTrue(self.get_table_element(self.table_name, rows_displayed), msg=("not enough rows displayed"))
self.assertFalse(self.get_table_element(self.table_name, rows_displayed + 1), \
msg=("more rows displayed than expected"))
@@ -888,7 +888,7 @@ class toaster_cases(toaster_cases_base):
temp_element.find_element_by_xpath("..//*[@class='icon-filter filtered']").click()
avail_options = self.driver.find_elements_by_xpath("//*[@id='" + filter_dict[key] + "']//*[@name='filter'][not(@disabled)]")
except:
- print "in exception"
+ print("in exception")
self.find_element_by_text("Show all tasks").click()
# self.driver.find_element_by_xpath("//*[@id='searchform']/button[2]").click()
temp_element = self.find_element_by_link_text_in_table(self.table_name, key)
@@ -899,9 +899,9 @@ class toaster_cases(toaster_cases_base):
for item in ['order', 'task_name', 'executed', 'outcome', 'recipe_name', 'recipe_version']:
try:
self.find_element_by_xpath_in_table(self.table_name, "./tbody/tr[1]/*[@class='" + item + "']/a").click()
- except NoSuchElementException, e:
+ except NoSuchElementException as e:
# let it go...
- print 'no item in the colum' + item
+ print('no item in the colum' + item)
# insert screen shot here
self.save_screenshot(screenshot_type='selenium', append_name='step11')
self.driver.back()
@@ -992,13 +992,13 @@ class toaster_cases(toaster_cases_base):
self.table_name = 'otable'
# This is how we find the "default" rows-number!
rows_displayed = int(Select(self.driver.find_element_by_css_selector("select.pagesize")).first_selected_option.text)
- print rows_displayed
+ print(rows_displayed)
self.assertTrue(self.get_table_element(self.table_name, rows_displayed))
self.assertFalse(self.get_table_element(self.table_name, rows_displayed + 1))
# Check the default table is sorted by Recipe
tasks_column_count = len(self.driver.find_elements_by_xpath("/html/body/div[2]/div/div[2]/div[2]/table/tbody/tr/td[1]"))
- print tasks_column_count
+ print(tasks_column_count)
default_column_list = self.get_table_column_text_by_column_number(self.table_name, 1)
#print default_column_list
@@ -1095,7 +1095,7 @@ class toaster_cases(toaster_cases_base):
# Bug 5919
for key in table_head_dict:
- print key
+ print(key)
self.find_element_by_link_text_in_table(self.table_name, key).click()
self.driver.find_element_by_id("edit-columns-button").click()
self.driver.find_element_by_id(table_head_dict[key]).click()
@@ -1167,7 +1167,7 @@ class toaster_cases(toaster_cases_base):
check_list = ['Dependencies', 'Layer branch', 'Layer commit', 'Reverse dependencies']
head_list = self.get_table_head_text('otable')
time.sleep(2)
- print head_list
+ print(head_list)
for item in check_list:
self.assertTrue(item in head_list, msg=("item %s not in head row" % item))
# un-check 'em all
@@ -1226,8 +1226,8 @@ class toaster_cases(toaster_cases_base):
tasks_row_count = len(driver.find_elements_by_xpath("//*[@id='"+self.table_name+"']/table/tbody/tr/td[1]"))
tasks_column_count = len(driver.find_elements_by_xpath("//*[@id='"+self.table_name+"']/table/tbody/tr[1]/td"))
- print 'rows: '+str(tasks_row_count)
- print 'columns: '+str(tasks_column_count)
+ print('rows: '+str(tasks_row_count))
+ print('columns: '+str(tasks_column_count))
Tasks_column = self.get_table_column_text_by_column_number(self.table_name, 2)
print ("Tasks_column=", Tasks_column)
@@ -1253,9 +1253,9 @@ class toaster_cases(toaster_cases_base):
driver.find_element_by_partial_link_text("Packages (").click()
packages_name = driver.find_element_by_partial_link_text("Packages (").text
- print packages_name
+ print(packages_name)
packages_num = int(filter(str.isdigit, repr(packages_name)))
- print packages_num
+ print(packages_num)
#switch the table to show more than 10 rows at a time
self.driver.find_element_by_xpath("//*[@id='packages-built']/div[1]/div/select").click()
@@ -1263,7 +1263,7 @@ class toaster_cases(toaster_cases_base):
self.driver.find_element_by_xpath("//*[@id='packages-built']/div[1]/div/select").send_keys(Keys.ENTER)
packages_row_count = len(driver.find_elements_by_xpath("//*[@id='otable']/tbody/tr/td[1]"))
- print packages_row_count
+ print(packages_row_count)
if packages_num != packages_row_count:
print ("Error! The packages number is not correct")
@@ -1272,20 +1272,20 @@ class toaster_cases(toaster_cases_base):
driver.find_element_by_partial_link_text("Build dependencies (").click()
depends_name = driver.find_element_by_partial_link_text("Build dependencies (").text
- print depends_name
- depends_num = int(filter(str.isdigit, repr(depends_name)))
- print depends_num
+ print(depends_name)
+ depends_num = int(list(filter(str.isdigit, repr(depends_name))))
+ print(depends_num)
if depends_num == 0:
depends_message = repr(driver.find_element_by_css_selector("div.alert.alert-info").text)
- print depends_message
+ print(depends_message)
if depends_message.find("has no build dependencies.") < 0:
print ("Error! The message isn't expected.")
else:
print ("The message is expected")
else:
depends_row_count = len(driver.find_elements_by_xpath("//*[@id='dependencies']/table/tbody/tr/td[1]"))
- print depends_row_count
+ print(depends_row_count)
if depends_num != depends_row_count:
print ("Error! The dependent packages number is not correct")
else:
@@ -1293,13 +1293,13 @@ class toaster_cases(toaster_cases_base):
driver.find_element_by_partial_link_text("Reverse build dependencies (").click()
rdepends_name = driver.find_element_by_partial_link_text("Reverse build dependencies (").text
- print rdepends_name
+ print(rdepends_name)
rdepends_num = int(filter(str.isdigit, repr(rdepends_name)))
- print rdepends_num
+ print(rdepends_num)
if rdepends_num == 0:
rdepends_message = repr(driver.find_element_by_css_selector("#brought-in-by > div.alert.alert-info").text)
- print rdepends_message
+ print(rdepends_message)
if rdepends_message.find("has no reverse build dependencies.") < 0:
print ("Error! The message isn't expected.")
else:
@@ -1319,8 +1319,8 @@ class toaster_cases(toaster_cases_base):
native_tasks_row_count = len(driver.find_elements_by_xpath("//*[@id='information']/table/tbody/tr/td[1]"))
native_tasks_column_count = len(driver.find_elements_by_xpath("//*[@id='information']/table/tbody/tr[1]/td"))
- print native_tasks_row_count
- print native_tasks_column_count
+ print(native_tasks_row_count)
+ print(native_tasks_column_count)
Native_Tasks_column = self.get_table_column_text_by_column_number(self.table_name, 2)
print ("Native_Tasks_column=", Native_Tasks_column)
@@ -1346,15 +1346,15 @@ class toaster_cases(toaster_cases_base):
driver.find_element_by_partial_link_text("Packages (").click()
native_packages_name = driver.find_element_by_partial_link_text("Packages (").text
- print native_packages_name
+ print(native_packages_name)
native_packages_num = int(filter(str.isdigit, repr(native_packages_name)))
- print native_packages_num
+ print(native_packages_num)
if native_packages_num != 0:
print ("Error! Native task shouldn't have any packages.")
else:
native_package_message = repr(driver.find_element_by_css_selector("#packages-built > div.alert.alert-info").text)
- print native_package_message
+ print(native_package_message)
if native_package_message.find("does not build any packages.") < 0:
print ("Error! The message for native task isn't expected.")
else:
@@ -1362,12 +1362,12 @@ class toaster_cases(toaster_cases_base):
driver.find_element_by_partial_link_text("Build dependencies (").click()
native_depends_name = driver.find_element_by_partial_link_text("Build dependencies (").text
- print native_depends_name
+ print(native_depends_name)
native_depends_num = int(filter(str.isdigit, repr(native_depends_name)))
- print native_depends_num
+ print(native_depends_num)
native_depends_row_count = len(driver.find_elements_by_xpath("//*[@id='dependencies']/table/tbody/tr/td[1]"))
- print native_depends_row_count
+ print(native_depends_row_count)
if native_depends_num != native_depends_row_count:
print ("Error! The dependent packages number is not correct")
@@ -1376,12 +1376,12 @@ class toaster_cases(toaster_cases_base):
driver.find_element_by_partial_link_text("Reverse build dependencies (").click()
native_rdepends_name = driver.find_element_by_partial_link_text("Reverse build dependencies (").text
- print native_rdepends_name
+ print(native_rdepends_name)
native_rdepends_num = int(filter(str.isdigit, repr(native_rdepends_name)))
- print native_rdepends_num
+ print(native_rdepends_num)
native_rdepends_row_count = len(driver.find_elements_by_xpath("//*[@id='brought-in-by']/table/tbody/tr/td[1]"))
- print native_rdepends_row_count
+ print(native_rdepends_row_count)
if native_rdepends_num != native_rdepends_row_count:
print ("Error! The reverse dependent packages number is not correct")
@@ -1413,8 +1413,8 @@ class toaster_cases(toaster_cases_base):
# step 5
self.driver.find_element_by_css_selector("i.icon-remove").click()
head_list = self.get_table_head_text('otable')
- print head_list
- print len(head_list)
+ print(head_list)
+ print(len(head_list))
self.assertTrue(head_list == ['Variable', 'Value', 'Set in file', 'Description'], \
msg=("head row contents wrong"))
# step 8
@@ -1830,7 +1830,7 @@ class toaster_cases(toaster_cases_base):
try:
self.driver.find_element_by_partial_link_text("Packages included")
self.driver.find_element_by_partial_link_text("Directory structure")
- except Exception,e:
+ except Exception as e:
self.log.error(e)
self.assertFalse(True)
# step 4
@@ -2014,13 +2014,13 @@ class toaster_cases(toaster_cases_base):
for i in range(0,4):
data[i] = data[i][0]
data.sort()
- print data
+ print(data)
json_parse = json.loads(open('toasterconf.json').read())
json_data = []
for i in range (0,4):
json_data.append(json_parse['releases'][i]['name'])
json_data.sort()
- print json_data
+ print(json_data)
self.failUnless(data == json_data)
##############
@@ -2036,11 +2036,11 @@ class toaster_cases(toaster_cases_base):
data = cursor.fetchall()
for i in range(0,6):
data[i] = data[i][0]
- print data
+ print(data)
json_parse = json.loads(open('toasterconf.json').read())
json_data=json_parse['config']
json_data = json_data.values()
- print json_data
+ print(json_data)
self.failUnless(data == json_data)
@@ -2057,12 +2057,12 @@ class toaster_cases(toaster_cases_base):
data = cursor.fetchall()
for i in range(0,3):
data[i] = data[i][0]
- print data
+ print(data)
json_parse = json.loads(open('toasterconf.json').read())
json_data = []
for i in range(0,3):
json_data.append(json_parse['layersources'][i]['name'])
- print json_data
+ print(json_data)
self.failUnless(set(data) == set(json_data))
##############
@@ -2077,10 +2077,10 @@ class toaster_cases(toaster_cases_base):
cursor.execute(query)
data = cursor.fetchall()
data = data[0][0]
- print data
+ print(data)
json_parse = json.loads(open('toasterconf.json').read())
json_data = json_parse['defaultrelease']
- print json_data
+ print(json_data)
self.failUnless(set(data) == set(json_data))
##############
@@ -2090,7 +2090,7 @@ class toaster_cases(toaster_cases_base):
self.case_no = self.get_case_number()
self.log.info(' CASE %s log: ' % str(self.case_no))
- print 'Checking branches for "Local Yocto Project"'
+ print('Checking branches for "Local Yocto Project"')
con=sqlite.connect('toaster.sqlite')
cursor = con.cursor()
query = "select name from orm_branch where layer_source_id=1;"
@@ -2102,15 +2102,15 @@ class toaster_cases(toaster_cases_base):
data[i] = data[i][0]
except:
pass
- print data
+ print(data)
json_parse = json.loads(open('toasterconf.json').read())
json_location = json_parse['layersources'][0]['name']
- print json_location
+ print(json_location)
json_data = json_parse['layersources'][0]['branches']
- print json_data
+ print(json_data)
self.failUnless(set(data) == set(json_data))
- print 'Checking branches for "OpenEmbedded"'
+ print('Checking branches for "OpenEmbedded"')
con=sqlite.connect('toaster.sqlite')
cursor = con.cursor()
query = "select name from orm_branch where layer_source_id=3;"
@@ -2119,15 +2119,15 @@ class toaster_cases(toaster_cases_base):
lenght = len(data)
for i in range(0,lenght):
data[i] = data[i][0]
- print data
+ print(data)
json_parse = json.loads(open('toasterconf.json').read())
json_location = json_parse['layersources'][1]['name']
- print json_location
+ print(json_location)
json_data = json_parse['layersources'][1]['branches']
- print json_data
+ print(json_data)
self.failUnless(set(data) == set(json_data))
- print 'Checking branches for "Imported layers"'
+ print('Checking branches for "Imported layers"')
con=sqlite.connect('toaster.sqlite')
cursor = con.cursor()
query = "select name from orm_branch where layer_source_id=2;"
@@ -2136,12 +2136,12 @@ class toaster_cases(toaster_cases_base):
lenght = len(data)
for i in range(0,lenght):
data[i] = data[i][0]
- print data
+ print(data)
json_parse = json.loads(open('toasterconf.json').read())
json_location = json_parse['layersources'][2]['name']
- print json_location
+ print(json_location)
json_data = json_parse['layersources'][2]['branches']
- print json_data
+ print(json_data)
self.failUnless(set(data) == set(json_data))
@@ -2158,12 +2158,12 @@ class toaster_cases(toaster_cases_base):
data = cursor.fetchall()
for i in range(0,4):
data[i] = data[i][0]
- print data
+ print(data)
json_parse = json.loads(open('toasterconf.json').read())
json_data = []
for i in range(0,4):
json_data.append(json_parse['bitbake'][i]['name'])
- print json_data
+ print(json_data)
self.failUnless(set(data) == set(json_data))
##############
@@ -2182,7 +2182,7 @@ class toaster_cases(toaster_cases_base):
query = "select count(name) from orm_project where name = 'new-test-project';"
cursor.execute(query)
data = cursor.fetchone()
- print 'data: %s' % data
+ print('data: %s' % data)
self.failUnless(data >= 1)
##############
@@ -2275,7 +2275,7 @@ class toaster_cases(toaster_cases_base):
data = data[0][0]
except:
pass
- print data
+ print(data)
self.failUnless(data == 'toaster_admin')
##############
@@ -2324,7 +2324,7 @@ class toaster_cases(toaster_cases_base):
query = "select a.name, a.value from orm_projectvariable a, orm_project b where a.project_id = b.id and b.name = 'new-default-project';"
cursor.execute(query)
data = dict(cursor.fetchall())
- print data
+ print(data)
default_values = {u'IMAGE_INSTALL_append': u'', u'PACKAGE_CLASSES': u'package_rpm', u'MACHINE': u'qemux86', u'SDKMACHINE': u'x86_64', u'DISTRO': u'poky', u'IMAGE_FSTYPES': u'ext3 jffs2 tar.bz2'}
self.failUnless(data == default_values)
@@ -2341,7 +2341,7 @@ class toaster_cases(toaster_cases_base):
query = "select layercommit_id from orm_projectlayer a, orm_project b where a.project_id=b.id and b.name='new-default-project';"
cursor.execute(query)
data_initial = cursor.fetchall()
- print data_initial
+ print(data_initial)
self.driver.maximize_window()
self.driver.get('localhost:8000')#self.base_url)
@@ -2362,7 +2362,7 @@ class toaster_cases(toaster_cases_base):
query = "select layercommit_id from orm_projectlayer a, orm_project b where a.project_id=b.id and b.name='new-default-project';"
cursor.execute(query)
data_changed = cursor.fetchall()
- print data_changed
+ print(data_changed)
#resetting release to default
self.driver.find_element_by_id('release-change-toggle').click()
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/urlcheck.py b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/urlcheck.py
index 0820f82e2..001fcee96 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/urlcheck.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/contrib/tts/urlcheck.py
@@ -26,12 +26,12 @@ def validate_html5(url):
warnings = int(resp['x-w3c-validator-warnings'])
if status == 'Invalid':
- config.logger.warn("Failed %s is %s\terrors %s warnings %s (check at %s)", url, status, errors, warnings, urlrequest)
+ config.logger.warning("Failed %s is %s\terrors %s warnings %s (check at %s)", url, status, errors, warnings, urlrequest)
else:
config.logger.debug("OK! %s", url)
except Exception as exc:
- config.logger.warn("Failed validation call: %s", exc)
+ config.logger.warning("Failed validation call: %s", exc)
return (status, errors, warnings)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/manage.py b/import-layers/yocto-poky/bitbake/lib/toaster/manage.py
index ceaa11bfc..0c7ea5088 100755
--- a/import-layers/yocto-poky/bitbake/lib/toaster/manage.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/manage.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import os
import sys
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/README b/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/README
new file mode 100644
index 000000000..1b1c660aa
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/README
@@ -0,0 +1,30 @@
+# Fixtures directory
+
+Fixtures are data dumps that can be loaded into Toaster's database to provide
+configuration and data.
+
+In this directory we have the fixtures which are loaded the first time you start Toaster.
+This is to provide useful default values and metadata to Toaster.
+
+ - settings.xml This Contains Toaster wide settings, such as the default values for
+ certain bitbake variables.
+
+ - poky.xml This is the default release data for supported poky based setup
+
+ - oe-core.xml This is the default release data for supported oe-core based setups
+
+# Custom data/configuration
+
+ - custom.xml
+
+To add custom initial data/configuration to Toaster place a file called
+"custom.xml" in this directory. If present it will be loaded into the database.
+We suggest that this is used to overlay any configuration already done.
+All objects loaded with the same primary keys overwrite the existing data.
+Data can be provided in XML, JSON and if installed YAML formats.
+
+# To load data at any point in time
+
+Use the django management command manage.py loaddata <your fixture file>
+For further information see the Django command documentation at:
+https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-loaddata
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/oe-core.xml b/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/oe-core.xml
new file mode 100644
index 000000000..a6c834f44
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/oe-core.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<django-objects version="1.0">
+ <!-- Set the project default value for DISTRO -->
+ <object model="orm.toastersetting" pk="1">
+ <field type="CharField" name="name">DEFCONF_DISTRO</field>
+ <field type="CharField" name="value">nodistro</field>
+ </object>
+
+ <!-- Bitbake versions which correspond to the metadata release -->
+ <object model="orm.bitbakeversion" pk="1">
+ <field type="CharField" name="name">morty</field>
+ <field type="CharField" name="giturl">git://git.openembedded.org/bitbake</field>
+ <field type="CharField" name="branch">1.32</field>
+ </object>
+ <object model="orm.bitbakeversion" pk="2">
+ <field type="CharField" name="name">HEAD</field>
+ </object>
+
+ <!-- Releases available -->
+ <object model="orm.release" pk="1">
+ <field type="CharField" name="name">morty</field>
+ <field type="CharField" name="description">Openembedded Morty</field>
+ <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">1</field>
+ <field type="CharField" name="branch_name">morty</field>
+ <field type="TextField" name="helptext">Toaster will run your builds using the tip of the &lt;a href=\"http://cgit.openembedded.org/openembedded-core/log/?h=morty\"&gt;OpenEmbedded Morty&lt;/a&gt; branch.</field>
+ </object>
+ <object model="orm.release" pk="2">
+ <field type="CharField" name="name">local</field>
+ <field type="CharField" name="description">Local Openembedded</field>
+ <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">2</field>
+ <field type="CharField" name="branch_name">HEAD</field>
+ <field type="TextField" name="helptext">Toaster will run your builds with the version of OpenEmbedded that you have cloned or downloaded to your computer.</field>
+ </object>
+
+ <!-- Default layers for each release -->
+ <object model="orm.releasedefaultlayer" pk="1">
+ <field rel="ManyToOneRel" to="orm.release" name="release">1</field>
+ <field type="CharField" name="layer_name">openembedded-core</field>
+ </object>
+ <object model="orm.releasedefaultlayer" pk="4">
+ <field rel="ManyToOneRel" to="orm.release" name="release">2</field>
+ <field type="CharField" name="layer_name">openembedded-core</field>
+ </object>
+
+ <!-- TYPE_LOCAL = 0 Layers for the Local release -->
+ <object model="orm.layer" pk="1">
+ <field type="CharField" name="name">openembedded-core</field>
+ <field type="CharField" name="vcs_url">git://git.openembedded.org/openembedded-core</field>
+ </object>
+ <object model="orm.layer_version" pk="1">
+ <field rel="ManyToOneRel" to="orm.layer" name="layer">1</field>
+ <field rel="ManyToOneRel" to="orm.release" name="release">2</field>
+ <field type="CharField" name="local_path">OE-CORE-LAYER-DIR</field>
+ <field type="CharField" name="branch">HEAD</field>
+ <field type="CharField" name="dirpath">meta</field>
+ <field type="IntegerField" name="layer_source">0</field>
+ </object>
+
+</django-objects>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/poky.xml b/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/poky.xml
new file mode 100644
index 000000000..c192baa42
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/poky.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<django-objects version="1.0">
+ <!-- Set the project default value for DISTRO -->
+ <object model="orm.toastersetting" pk="1">
+ <field type="CharField" name="name">DEFCONF_DISTRO</field>
+ <field type="CharField" name="value">poky</field>
+ </object>
+
+ <!-- Bitbake versions which correspond to the metadata release -->
+ <object model="orm.bitbakeversion" pk="1">
+ <field type="CharField" name="name">morty</field>
+ <field type="CharField" name="giturl">git://git.yoctoproject.org/poky</field>
+ <field type="CharField" name="branch">morty</field>
+ <field type="CharField" name="dirpath">bitbake</field>
+ </object>
+ <object model="orm.bitbakeversion" pk="2">
+ <field type="CharField" name="name">HEAD</field>
+ <field type="CharField" name="giturl">git://git.yoctoproject.org/poky</field>
+ <field type="CharField" name="branch">HEAD</field>
+ <field type="CharField" name="dirpath">bitbake</field>
+ </object>
+
+ <!-- Releases available -->
+ <object model="orm.release" pk="1">
+ <field type="CharField" name="name">morty</field>
+ <field type="CharField" name="description">Yocto Project 2.2 "Morty"</field>
+ <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">1</field>
+ <field type="CharField" name="branch_name">morty</field>
+ <field type="TextField" name="helptext">Toaster will run your builds using the tip of the &lt;a href="http://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?h=morty"&gt;Yocto Project Morty branch&lt;/a&gt;.</field>
+ </object>
+ <object model="orm.release" pk="2">
+ <field type="CharField" name="name">local</field>
+ <field type="CharField" name="description">Local Yocto Project</field>
+ <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">2</field>
+ <field type="CharField" name="branch_name">HEAD</field>
+ <field type="TextField" name="helptext">Toaster will run your builds with the version of the Yocto Project you have cloned or downloaded to your computer.</field>
+ </object>
+
+ <!-- Default layers for each release -->
+ <object model="orm.releasedefaultlayer" pk="1">
+ <field rel="ManyToOneRel" to="orm.release" name="release">1</field>
+ <field type="CharField" name="layer_name">openembedded-core</field>
+ </object>
+ <object model="orm.releasedefaultlayer" pk="2">
+ <field rel="ManyToOneRel" to="orm.release" name="release">1</field>
+ <field type="CharField" name="layer_name">meta-poky</field>
+ </object>
+ <object model="orm.releasedefaultlayer" pk="3">
+ <field rel="ManyToOneRel" to="orm.release" name="release">1</field>
+ <field type="CharField" name="layer_name">meta-yocto-bsp</field>
+ </object>
+ <object model="orm.releasedefaultlayer" pk="4">
+ <field rel="ManyToOneRel" to="orm.release" name="release">2</field>
+ <field type="CharField" name="layer_name">openembedded-core</field>
+ </object>
+ <object model="orm.releasedefaultlayer" pk="5">
+ <field rel="ManyToOneRel" to="orm.release" name="release">2</field>
+ <field type="CharField" name="layer_name">meta-poky</field>
+ </object>
+ <object model="orm.releasedefaultlayer" pk="6">
+ <field rel="ManyToOneRel" to="orm.release" name="release">2</field>
+ <field type="CharField" name="layer_name">meta-yocto-bsp</field>
+ </object>
+
+ <!-- Layers for the Local release
+ layersource TYPE_LOCAL = 0
+ -->
+ <object model="orm.layer" pk="1">
+ <field type="CharField" name="name">openembedded-core</field>
+ <field type="CharField" name="layer_index_url"></field>
+ <field type="CharField" name="vcs_url">git://git.yoctoproject.org/poky</field>
+ </object>
+ <object model="orm.layer_version" pk="1">
+ <field rel="ManyToOneRel" to="orm.layer" name="layer">1</field>
+ <field type="IntegerField" name="layer_source">0</field>
+ <field rel="ManyToOneRel" to="orm.release" name="release">2</field>
+ <field type="CharField" name="branch">HEAD</field>
+ <field type="CharField" name="commit">HEAD</field>
+ <field type="CharField" name="dirpath">meta</field>
+ </object>
+
+
+ <object model="orm.layer" pk="2">
+ <field type="CharField" name="name">meta-poky</field>
+ <field type="CharField" name="layer_index_url"></field>
+ <field type="CharField" name="vcs_url">git://git.yoctoproject.org/poky</field>
+ </object>
+ <object model="orm.layer_version" pk="2">
+ <field rel="ManyToOneRel" to="orm.layer" name="layer">2</field>
+ <field type="IntegerField" name="layer_source">0</field>
+ <field rel="ManyToOneRel" to="orm.release" name="release">2</field>
+ <field type="CharField" name="branch">HEAD</field>
+ <field type="CharField" name="commit">HEAD</field>
+ <field type="CharField" name="dirpath">meta-poky</field>
+ </object>
+
+
+ <object model="orm.layer" pk="3">
+ <field type="CharField" name="name">meta-yocto-bsp</field>
+ <field type="CharField" name="layer_index_url"></field>
+ <field type="CharField" name="vcs_url">git://git.yoctoproject.org/poky</field>
+ </object>
+ <object model="orm.layer_version" pk="3">
+ <field rel="ManyToOneRel" to="orm.layer" name="layer">3</field>
+ <field type="IntegerField" name="layer_source">0</field>
+ <field rel="ManyToOneRel" to="orm.release" name="release">2</field>
+ <field type="CharField" name="branch">HEAD</field>
+ <field type="CharField" name="commit">HEAD</field>
+ <field type="CharField" name="dirpath">meta-yocto-bsp</field>
+ </object>
+</django-objects>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/settings.xml b/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/settings.xml
new file mode 100644
index 000000000..ee6a20285
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/fixtures/settings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<django-objects version="1.0">
+ <!-- Default project settings -->
+ <!-- pk=1 is DISTRO -->
+ <object model="orm.toastersetting" pk="2">
+ <field type="CharField" name="name">DEFAULT_RELEASE</field>
+ <field type="CharField" name="value">morty</field>
+ </object>
+ <object model="orm.toastersetting" pk="3">
+ <field type="CharField" name="name">DEFCONF_PACKAGE_CLASSES</field>
+ <field type="CharField" name="value">package_rpm</field>
+ </object>
+ <object model="orm.toastersetting" pk="4">
+ <field type="CharField" name="name">DEFCONF_MACHINE</field>
+ <field type="CharField" name="value">qemux86</field>
+ </object>
+ <object model="orm.toastersetting" pk="5">
+ <field type="CharField" name="name">DEFCONF_SSTATE_DIR</field>
+ <field type="CharField" name="value">${TOPDIR}/../sstate-cache</field>
+ </object>
+ <object model="orm.toastersetting" pk="6">
+ <field type="CharField" name="name">DEFCONF_IMAGE_INSTALL_append</field>
+ <field type="CharField" name="value"></field>
+ </object>
+ <object model="orm.toastersetting" pk="7">
+ <field type="CharField" name="name">DEFCONF_IMAGE_FSTYPES</field>
+ <field type="CharField" name="value">ext3 jffs2 tar.bz2</field>
+ </object>
+ <object model="orm.toastersetting" pk="8">
+ <field type="CharField" name="name">DEFCONF_DL_DIR</field>
+ <field type="CharField" name="value">${TOPDIR}/../downloads</field>
+ </object>
+</django-objects>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/management/commands/lsupdates.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/management/commands/lsupdates.py
index 75e9513fc..8ff120e0b 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/orm/management/commands/lsupdates.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/management/commands/lsupdates.py
@@ -1,12 +1,334 @@
-from django.core.management.base import NoArgsCommand, CommandError
-from orm.models import LayerSource
+#
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from django.core.management.base import NoArgsCommand
+
+from orm.models import LayerSource, Layer, Release, Layer_Version
+from orm.models import LayerVersionDependency, Machine, Recipe
+
import os
+import sys
+
+import json
+import logging
+import threading
+import time
+logger = logging.getLogger("toaster")
+
+DEFAULT_LAYERINDEX_SERVER = "http://layers.openembedded.org/layerindex/api/"
+
+
+class Spinner(threading.Thread):
+ """ A simple progress spinner to indicate download/parsing is happening"""
+ def __init__(self, *args, **kwargs):
+ super(Spinner, self).__init__(*args, **kwargs)
+ self.setDaemon(True)
+ self.signal = True
+
+ def run(self):
+ os.system('setterm -cursor off')
+ while self.signal:
+ for char in ["/", "-", "\\", "|"]:
+ sys.stdout.write("\r" + char)
+ sys.stdout.flush()
+ time.sleep(0.25)
+ os.system('setterm -cursor on')
+
+ def stop(self):
+ self.signal = False
+
class Command(NoArgsCommand):
- args = ""
- help = "Updates locally cached information from all LayerSources"
+ args = ""
+ help = "Updates locally cached information from a layerindex server"
+
+ def mini_progress(self, what, i, total):
+ i = i + 1
+ pec = (float(i)/float(total))*100
+
+ sys.stdout.write("\rUpdating %s %d%%" %
+ (what,
+ pec))
+ sys.stdout.flush()
+ if int(pec) is 100:
+ sys.stdout.write("\n")
+ sys.stdout.flush()
+
+ def update(self):
+ """
+ Fetches layer, recipe and machine information from a layerindex
+ server
+ """
+ os.system('setterm -cursor off')
+
+ self.apiurl = DEFAULT_LAYERINDEX_SERVER
+
+ assert self.apiurl is not None
+ try:
+ from urllib.request import urlopen, URLError
+ from urllib.parse import urlparse
+ except ImportError:
+ from urllib2 import urlopen, URLError
+ from urlparse import urlparse
+
+ proxy_settings = os.environ.get("http_proxy", None)
+ oe_core_layer = 'openembedded-core'
+
+ def _get_json_response(apiurl=DEFAULT_LAYERINDEX_SERVER):
+ http_progress = Spinner()
+ http_progress.start()
+
+ _parsedurl = urlparse(apiurl)
+ path = _parsedurl.path
+
+ # logger.debug("Fetching %s", apiurl)
+ try:
+ res = urlopen(apiurl)
+ except URLError as e:
+ raise Exception("Failed to read %s: %s" % (path, e.reason))
+
+ parsed = json.loads(res.read().decode('utf-8'))
+
+ http_progress.stop()
+ return parsed
+
+ # verify we can get the basic api
+ try:
+ apilinks = _get_json_response()
+ except Exception as e:
+ import traceback
+ if proxy_settings is not None:
+ logger.info("EE: Using proxy %s" % proxy_settings)
+ logger.warning("EE: could not connect to %s, skipping update:"
+ "%s\n%s" % (self.apiurl, e, traceback.format_exc()))
+ return
+
+ # update branches; only those that we already have names listed in the
+ # Releases table
+ whitelist_branch_names = [rel.branch_name
+ for rel in Release.objects.all()]
+ if len(whitelist_branch_names) == 0:
+ raise Exception("Failed to make list of branches to fetch")
+
+ logger.info("Fetching metadata releases for %s",
+ " ".join(whitelist_branch_names))
+
+ branches_info = _get_json_response(apilinks['branches'] +
+ "?filter=name:%s"
+ % "OR".join(whitelist_branch_names))
+
+ # Map the layer index branches to toaster releases
+ li_branch_id_to_toaster_release = {}
+
+ total = len(branches_info)
+ for i, branch in enumerate(branches_info):
+ li_branch_id_to_toaster_release[branch['id']] = \
+ Release.objects.get(name=branch['name'])
+ self.mini_progress("Releases", i, total)
+
+ # keep a track of the layerindex (li) id mappings so that
+ # layer_versions can be created for these layers later on
+ li_layer_id_to_toaster_layer_id = {}
+
+ logger.info("Fetching layers")
+
+ layers_info = _get_json_response(apilinks['layerItems'])
+
+ total = len(layers_info)
+ for i, li in enumerate(layers_info):
+ # Special case for the openembedded-core layer
+ if li['name'] == oe_core_layer:
+ try:
+ # If we have an existing openembedded-core for example
+ # from the toasterconf.json augment the info using the
+ # layerindex rather than duplicate it
+ oe_core_l = Layer.objects.get(name=oe_core_layer)
+ # Take ownership of the layer as now coming from the
+ # layerindex
+ oe_core_l.summary = li['summary']
+ oe_core_l.description = li['description']
+ oe_core_l.vcs_web_url = li['vcs_web_url']
+ oe_core_l.vcs_web_tree_base_url = \
+ li['vcs_web_tree_base_url']
+ oe_core_l.vcs_web_file_base_url = \
+ li['vcs_web_file_base_url']
+
+ oe_core_l.save()
+ li_layer_id_to_toaster_layer_id[li['id']] = oe_core_l.pk
+ self.mini_progress("layers", i, total)
+ continue
+
+ except Layer.DoesNotExist:
+ pass
+
+ try:
+ l, created = Layer.objects.get_or_create(name=li['name'],
+ vcs_url=li['vcs_url'])
+ l.up_date = li['updated']
+ l.vcs_url = li['vcs_url']
+ l.vcs_web_url = li['vcs_web_url']
+ l.vcs_web_tree_base_url = li['vcs_web_tree_base_url']
+ l.vcs_web_file_base_url = li['vcs_web_file_base_url']
+ l.summary = li['summary']
+ l.description = li['description']
+ l.save()
+ except Layer.MultipleObjectsReturned:
+ logger.info("Skipped %s as we found multiple layers and "
+ "don't know which to update" %
+ li['name'])
+
+ li_layer_id_to_toaster_layer_id[li['id']] = l.pk
+
+ self.mini_progress("layers", i, total)
+
+ # update layer_versions
+ logger.info("Fetching layer versions")
+ layerbranches_info = _get_json_response(
+ apilinks['layerBranches'] + "?filter=branch__name:%s" %
+ "OR".join(whitelist_branch_names))
+
+ # Map Layer index layer_branch object id to
+ # layer_version toaster object id
+ li_layer_branch_id_to_toaster_lv_id = {}
+
+ total = len(layerbranches_info)
+ for i, lbi in enumerate(layerbranches_info):
+
+ try:
+ lv, created = Layer_Version.objects.get_or_create(
+ layer_source=LayerSource.TYPE_LAYERINDEX,
+ layer=Layer.objects.get(
+ pk=li_layer_id_to_toaster_layer_id[lbi['layer']])
+ )
+ except KeyError:
+ logger.warning(
+ "No such layerindex layer referenced by layerbranch %d" %
+ lbi['layer'])
+ continue
+
+ lv.release = li_branch_id_to_toaster_release[lbi['branch']]
+ lv.up_date = lbi['updated']
+ lv.commit = lbi['actual_branch']
+ lv.dirpath = lbi['vcs_subdir']
+ lv.save()
+
+ li_layer_branch_id_to_toaster_lv_id[lbi['id']] =\
+ lv.pk
+ self.mini_progress("layer versions", i, total)
+
+ logger.info("Fetching layer version dependencies")
+ # update layer dependencies
+ layerdependencies_info = _get_json_response(
+ apilinks['layerDependencies'] +
+ "?filter=layerbranch__branch__name:%s" %
+ "OR".join(whitelist_branch_names))
+
+ dependlist = {}
+ for ldi in layerdependencies_info:
+ try:
+ lv = Layer_Version.objects.get(
+ pk=li_layer_branch_id_to_toaster_lv_id[ldi['layerbranch']])
+ except Layer_Version.DoesNotExist as e:
+ continue
+
+ if lv not in dependlist:
+ dependlist[lv] = []
+ try:
+ layer_id = li_layer_id_to_toaster_layer_id[ldi['dependency']]
+
+ dependlist[lv].append(
+ Layer_Version.objects.get(
+ layer_source=LayerSource.TYPE_LAYERINDEX,
+ layer__pk=layer_id))
+
+ except Layer_Version.DoesNotExist:
+ logger.warning("Cannot find layer version (ls:%s),"
+ "up_id:%s lv:%s" %
+ (self, ldi['dependency'], lv))
+
+ total = len(dependlist)
+ for i, lv in enumerate(dependlist):
+ LayerVersionDependency.objects.filter(layer_version=lv).delete()
+ for lvd in dependlist[lv]:
+ LayerVersionDependency.objects.get_or_create(layer_version=lv,
+ depends_on=lvd)
+ self.mini_progress("Layer version dependencies", i, total)
+
+ # update machines
+ logger.info("Fetching machine information")
+ machines_info = _get_json_response(
+ apilinks['machines'] + "?filter=layerbranch__branch__name:%s" %
+ "OR".join(whitelist_branch_names))
+
+ total = len(machines_info)
+ for i, mi in enumerate(machines_info):
+ mo, created = Machine.objects.get_or_create(
+ name=mi['name'],
+ layer_version=Layer_Version.objects.get(
+ pk=li_layer_branch_id_to_toaster_lv_id[mi['layerbranch']]))
+ mo.up_date = mi['updated']
+ mo.name = mi['name']
+ mo.description = mi['description']
+ mo.save()
+ self.mini_progress("machines", i, total)
+
+ # update recipes; paginate by layer version / layer branch
+ logger.info("Fetching recipe information")
+ recipes_info = _get_json_response(
+ apilinks['recipes'] + "?filter=layerbranch__branch__name:%s" %
+ "OR".join(whitelist_branch_names))
+
+ total = len(recipes_info)
+ for i, ri in enumerate(recipes_info):
+ try:
+ lv_id = li_layer_branch_id_to_toaster_lv_id[ri['layerbranch']]
+ lv = Layer_Version.objects.get(pk=lv_id)
+
+ ro, created = Recipe.objects.get_or_create(
+ layer_version=lv,
+ name=ri['pn']
+ )
+
+ ro.layer_version = lv
+ ro.up_date = ri['updated']
+ ro.name = ri['pn']
+ ro.version = ri['pv']
+ ro.summary = ri['summary']
+ ro.description = ri['description']
+ ro.section = ri['section']
+ ro.license = ri['license']
+ ro.homepage = ri['homepage']
+ ro.bugtracker = ri['bugtracker']
+ ro.file_path = ri['filepath'] + "/" + ri['filename']
+ if 'inherits' in ri:
+ ro.is_image = 'image' in ri['inherits'].split()
+ else: # workaround for old style layer index
+ ro.is_image = "-image-" in ri['pn']
+ ro.save()
+ except Exception as e:
+ logger.warning("Failed saving recipe %s", e)
+
+ self.mini_progress("recipes", i, total)
+ os.system('setterm -cursor on')
def handle_noargs(self, **options):
- for ls in LayerSource.objects.all():
- ls.update()
+ self.update()
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0007_auto_20160523_1446.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0007_auto_20160523_1446.py
new file mode 100644
index 000000000..b472e7cf0
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0007_auto_20160523_1446.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0006_add_cancelled_state'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='build',
+ name='outcome',
+ field=models.IntegerField(default=2, choices=[(0, 'Succeeded'), (1, 'Failed'), (2, 'In Progress'), (3, 'Cancelled')]),
+ ),
+ migrations.AlterField(
+ model_name='helptext',
+ name='area',
+ field=models.IntegerField(choices=[(0, 'variable')]),
+ ),
+ migrations.AlterField(
+ model_name='layer',
+ name='summary',
+ field=models.TextField(default=None, null=True, help_text='One-line description of the layer'),
+ ),
+ migrations.AlterField(
+ model_name='layer_version',
+ name='local_path',
+ field=models.FilePathField(default='/', max_length=1024),
+ ),
+ migrations.AlterField(
+ model_name='layersource',
+ name='sourcetype',
+ field=models.IntegerField(choices=[(0, 'local'), (1, 'layerindex'), (2, 'imported')]),
+ ),
+ migrations.AlterField(
+ model_name='logmessage',
+ name='level',
+ field=models.IntegerField(default=0, choices=[(0, 'info'), (1, 'warn'), (2, 'error'), (3, 'critical'), (-1, 'toaster exception')]),
+ ),
+ migrations.AlterField(
+ model_name='package',
+ name='installed_name',
+ field=models.CharField(default='', max_length=100),
+ ),
+ migrations.AlterField(
+ model_name='package_dependency',
+ name='dep_type',
+ field=models.IntegerField(choices=[(0, 'depends'), (1, 'depends'), (3, 'recommends'), (2, 'recommends'), (4, 'suggests'), (5, 'provides'), (6, 'replaces'), (7, 'conflicts')]),
+ ),
+ migrations.AlterField(
+ model_name='recipe_dependency',
+ name='dep_type',
+ field=models.IntegerField(choices=[(0, 'depends'), (1, 'rdepends')]),
+ ),
+ migrations.AlterField(
+ model_name='release',
+ name='branch_name',
+ field=models.CharField(default='', max_length=50),
+ ),
+ migrations.AlterField(
+ model_name='releasedefaultlayer',
+ name='layer_name',
+ field=models.CharField(default='', max_length=100),
+ ),
+ migrations.AlterField(
+ model_name='target_file',
+ name='inodetype',
+ field=models.IntegerField(choices=[(1, 'regular'), (2, 'directory'), (3, 'symlink'), (4, 'socket'), (5, 'fifo'), (6, 'character'), (7, 'block')]),
+ ),
+ migrations.AlterField(
+ model_name='task',
+ name='outcome',
+ field=models.IntegerField(default=-1, choices=[(-1, 'Not Available'), (0, 'Succeeded'), (1, 'Covered'), (2, 'Cached'), (3, 'Prebuilt'), (4, 'Failed'), (5, 'Empty')]),
+ ),
+ migrations.AlterField(
+ model_name='task',
+ name='script_type',
+ field=models.IntegerField(default=0, choices=[(0, 'N/A'), (2, 'Python'), (3, 'Shell')]),
+ ),
+ migrations.AlterField(
+ model_name='task',
+ name='sstate_result',
+ field=models.IntegerField(default=0, choices=[(0, 'Not Applicable'), (1, 'File not in cache'), (2, 'Failed'), (3, 'Succeeded')]),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0008_refactor_artifact_models.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0008_refactor_artifact_models.py
new file mode 100644
index 000000000..3367582a8
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0008_refactor_artifact_models.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0007_auto_20160523_1446'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='TargetKernelFile',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
+ ('file_name', models.FilePathField()),
+ ('file_size', models.IntegerField()),
+ ('target', models.ForeignKey(to='orm.Target')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='TargetSDKFile',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
+ ('file_name', models.FilePathField()),
+ ('file_size', models.IntegerField()),
+ ('target', models.ForeignKey(to='orm.Target')),
+ ],
+ ),
+ migrations.RemoveField(
+ model_name='buildartifact',
+ name='build',
+ ),
+ migrations.DeleteModel(
+ name='BuildArtifact',
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0009_target_package_manifest_path.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0009_target_package_manifest_path.py
new file mode 100644
index 000000000..c958f3070
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0009_target_package_manifest_path.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0008_refactor_artifact_models'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='target',
+ name='package_manifest_path',
+ field=models.CharField(null=True, max_length=500),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0010_delete_layer_source_references.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0010_delete_layer_source_references.py
new file mode 100644
index 000000000..f67388e99
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0010_delete_layer_source_references.py
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0009_target_package_manifest_path'),
+ ]
+
+ operations = [
+ migrations.AlterUniqueTogether(
+ name='releaselayersourcepriority',
+ unique_together=set([]),
+ ),
+ migrations.RemoveField(
+ model_name='releaselayersourcepriority',
+ name='layer_source',
+ ),
+ migrations.RemoveField(
+ model_name='releaselayersourcepriority',
+ name='release',
+ ),
+ migrations.DeleteModel(
+ name='ImportedLayerSource',
+ ),
+ migrations.DeleteModel(
+ name='LayerIndexLayerSource',
+ ),
+ migrations.DeleteModel(
+ name='LocalLayerSource',
+ ),
+ migrations.RemoveField(
+ model_name='recipe',
+ name='layer_source',
+ ),
+ migrations.RemoveField(
+ model_name='recipe',
+ name='up_id',
+ ),
+ migrations.AlterField(
+ model_name='layer',
+ name='up_date',
+ field=models.DateTimeField(default=django.utils.timezone.now, null=True),
+ ),
+ migrations.AlterField(
+ model_name='layer_version',
+ name='layer_source',
+ field=models.IntegerField(default=0, choices=[(0, 'local'), (1, 'layerindex'), (2, 'imported'), (3, 'build')]),
+ ),
+ migrations.AlterField(
+ model_name='layer_version',
+ name='up_date',
+ field=models.DateTimeField(default=django.utils.timezone.now, null=True),
+ ),
+ migrations.AlterUniqueTogether(
+ name='branch',
+ unique_together=set([]),
+ ),
+ migrations.AlterUniqueTogether(
+ name='layer',
+ unique_together=set([]),
+ ),
+ migrations.AlterUniqueTogether(
+ name='layer_version',
+ unique_together=set([]),
+ ),
+ migrations.AlterUniqueTogether(
+ name='layerversiondependency',
+ unique_together=set([]),
+ ),
+ migrations.AlterUniqueTogether(
+ name='machine',
+ unique_together=set([]),
+ ),
+ migrations.DeleteModel(
+ name='ReleaseLayerSourcePriority',
+ ),
+ migrations.RemoveField(
+ model_name='branch',
+ name='layer_source',
+ ),
+ migrations.RemoveField(
+ model_name='branch',
+ name='up_id',
+ ),
+ migrations.RemoveField(
+ model_name='layer',
+ name='layer_source',
+ ),
+ migrations.RemoveField(
+ model_name='layer',
+ name='up_id',
+ ),
+ migrations.RemoveField(
+ model_name='layer_version',
+ name='up_id',
+ ),
+ migrations.RemoveField(
+ model_name='layerversiondependency',
+ name='layer_source',
+ ),
+ migrations.RemoveField(
+ model_name='layerversiondependency',
+ name='up_id',
+ ),
+ migrations.RemoveField(
+ model_name='machine',
+ name='layer_source',
+ ),
+ migrations.RemoveField(
+ model_name='machine',
+ name='up_id',
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0011_delete_layersource.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0011_delete_layersource.py
new file mode 100644
index 000000000..75506961a
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0011_delete_layersource.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0010_delete_layer_source_references'),
+ ]
+
+ operations = [
+ migrations.DeleteModel(
+ name='LayerSource',
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0012_use_release_instead_of_up_branch.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0012_use_release_instead_of_up_branch.py
new file mode 100644
index 000000000..0e6bb8331
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0012_use_release_instead_of_up_branch.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+from django.db.models import Q
+
+
+def branch_to_release(apps, schema_editor):
+ Layer_Version = apps.get_model('orm', 'Layer_Version')
+ Release = apps.get_model('orm', 'Release')
+
+ print("Converting all layer version up_branches to releases")
+ # Find all the layer versions which have an upbranch and convert them to
+ # the release that they're for.
+ for layer_version in Layer_Version.objects.filter(
+ Q(release=None) & ~Q(up_branch=None)):
+ try:
+ # HEAD and local are equivalent
+ if "HEAD" in layer_version.up_branch.name:
+ release = Release.objects.get(name="local")
+ layer_version.commit = "HEAD"
+ layer_version.branch = "HEAD"
+ else:
+ release = Release.objects.get(
+ name=layer_version.up_branch.name)
+
+ layer_version.release = release
+ layer_version.save()
+ except Exception as e:
+ print("Couldn't work out an appropriate release for %s "
+ "the up_branch was %s "
+ "user the django admin interface to correct it" %
+ (layer_version.layer.name, layer_version.up_branch.name))
+ print(e)
+
+ continue
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0011_delete_layersource'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='layer_version',
+ name='release',
+ field=models.ForeignKey(to='orm.Release', default=None, null=True),
+ ),
+ migrations.RunPython(branch_to_release,
+ reverse_code=migrations.RunPython.noop),
+
+ migrations.RemoveField(
+ model_name='layer_version',
+ name='up_branch',
+ ),
+
+ migrations.DeleteModel(
+ name='Branch',
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0013_recipe_parse_progress_fields.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0013_recipe_parse_progress_fields.py
new file mode 100644
index 000000000..cc5c96d2d
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0013_recipe_parse_progress_fields.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0012_use_release_instead_of_up_branch'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='build',
+ name='recipes_parsed',
+ field=models.IntegerField(default=0),
+ ),
+ migrations.AddField(
+ model_name='build',
+ name='recipes_to_parse',
+ field=models.IntegerField(default=1),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0014_allow_empty_buildname.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0014_allow_empty_buildname.py
new file mode 100644
index 000000000..4749a14b2
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0014_allow_empty_buildname.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0013_recipe_parse_progress_fields'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='build',
+ name='build_name',
+ field=models.CharField(default='', max_length=100),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0015_layer_local_source_dir.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0015_layer_local_source_dir.py
new file mode 100644
index 000000000..9539cd72a
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/migrations/0015_layer_local_source_dir.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('orm', '0014_allow_empty_buildname'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='layer',
+ name='local_source_dir',
+ field=models.TextField(null=True, default=None),
+ ),
+ ]
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py
index 0b83b991b..a7de57c25 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/orm/models.py
@@ -21,8 +21,8 @@
from __future__ import unicode_literals
-from django.db import models, IntegrityError
-from django.db.models import F, Q, Avg, Max, Sum
+from django.db import models, IntegrityError, DataError
+from django.db.models import F, Q, Sum, Count
from django.utils import timezone
from django.utils.encoding import force_bytes
@@ -32,9 +32,11 @@ from django.core import validators
from django.conf import settings
import django.db.models.signals
-import os.path
+import sys
+import os
import re
import itertools
+from signal import SIGUSR1
import logging
logger = logging.getLogger("toaster")
@@ -77,7 +79,7 @@ if 'sqlite' in settings.DATABASES['default']['ENGINE']:
try:
obj = self.create(**params)
return obj, True
- except IntegrityError:
+ except (IntegrityError, DataError):
exc_info = sys.exc_info()
try:
return self.get(**lookup), False
@@ -102,7 +104,7 @@ class GitURLValidator(validators.URLValidator):
def GitURLField(**kwargs):
r = models.URLField(**kwargs)
- for i in xrange(len(r.validators)):
+ for i in range(len(r.validators)):
if isinstance(r.validators[i], validators.URLValidator):
r.validators[i] = GitURLValidator()
return r
@@ -116,39 +118,48 @@ class ToasterSetting(models.Model):
def __unicode__(self):
return "Setting %s = %s" % (self.name, self.value)
+
class ProjectManager(models.Manager):
def create_project(self, name, release):
if release is not None:
- prj = self.model(name = name, bitbake_version = release.bitbake_version, release = release)
+ prj = self.model(name=name,
+ bitbake_version=release.bitbake_version,
+ release=release)
else:
- prj = self.model(name = name, bitbake_version = None, release = None)
+ prj = self.model(name=name,
+ bitbake_version=None,
+ release=None)
prj.save()
- for defaultconf in ToasterSetting.objects.filter(name__startswith="DEFCONF_"):
+ for defaultconf in ToasterSetting.objects.filter(
+ name__startswith="DEFCONF_"):
name = defaultconf.name[8:]
- ProjectVariable.objects.create( project = prj,
- name = name,
- value = defaultconf.value)
+ ProjectVariable.objects.create(project=prj,
+ name=name,
+ value=defaultconf.value)
if release is None:
return prj
for rdl in release.releasedefaultlayer_set.all():
- try:
- lv = Layer_Version.objects.filter(layer__name = rdl.layer_name, up_branch__name = release.branch_name)[0].get_equivalents_wpriority(prj)[0]
- ProjectLayer.objects.create( project = prj,
- layercommit = lv,
- optional = False )
- except IndexError:
- # we may have no valid layer version objects, and that's ok
- pass
+ lv = Layer_Version.objects.filter(
+ layer__name=rdl.layer_name,
+ release=release).first()
+
+ if lv:
+ ProjectLayer.objects.create(project=prj,
+ layercommit=lv,
+ optional=False)
+ else:
+ logger.warning("Default project layer %s not found" %
+ rdl.layer_name)
return prj
# return single object with is_default = True
def get_or_create_default_project(self):
- projects = super(ProjectManager, self).filter(is_default = True)
+ projects = super(ProjectManager, self).filter(is_default=True)
if len(projects) > 1:
raise Exception('Inconsistent project data: multiple ' +
@@ -156,7 +167,8 @@ class ProjectManager(models.Manager):
elif len(projects) < 1:
options = {
'name': 'Command line builds',
- 'short_description': 'Project for builds started outside Toaster',
+ 'short_description':
+ 'Project for builds started outside Toaster',
'is_default': True
}
project = Project.objects.create(**options)
@@ -269,7 +281,7 @@ class Project(models.Model):
# guard on release, as it can be null
if self.release:
queryset = Layer_Version.objects.filter(
- (Q(up_branch__name=self.release.branch_name) &
+ (Q(release=self.release) &
Q(build=None) &
Q(project=None)) |
Q(project=self))
@@ -335,7 +347,15 @@ class Project(models.Model):
for l in self.projectlayer_set.all().order_by("pk"):
commit = l.layercommit.get_vcs_reference()
print("ii Building layer ", l.layercommit.layer.name, " at vcs point ", commit)
- BRLayer.objects.create(req = br, name = l.layercommit.layer.name, giturl = l.layercommit.layer.vcs_url, commit = commit, dirpath = l.layercommit.dirpath, layer_version=l.layercommit)
+ BRLayer.objects.create(
+ req=br,
+ name=l.layercommit.layer.name,
+ giturl=l.layercommit.layer.vcs_url,
+ commit=commit,
+ dirpath=l.layercommit.dirpath,
+ layer_version=l.layercommit,
+ local_source_dir=l.layercommit.layer.local_source_dir
+ )
br.state = BuildRequest.REQ_QUEUED
now = timezone.now()
@@ -357,6 +377,8 @@ class Project(models.Model):
except ProjectVariable.DoesNotExist:
pass
br.save()
+ signal_runbuilds()
+
except Exception:
# revert the build request creation since we're not done cleanly
br.delete()
@@ -386,9 +408,15 @@ class Build(models.Model):
completed_on = models.DateTimeField()
outcome = models.IntegerField(choices=BUILD_OUTCOME, default=IN_PROGRESS)
cooker_log_path = models.CharField(max_length=500)
- build_name = models.CharField(max_length=100)
+ build_name = models.CharField(max_length=100, default='')
bitbake_version = models.CharField(max_length=50)
+ # number of recipes to parse for this build
+ recipes_to_parse = models.IntegerField(default=1)
+
+ # number of recipes parsed so far for this build
+ recipes_parsed = models.IntegerField(default=0)
+
@staticmethod
def get_recent(project=None):
"""
@@ -415,14 +443,30 @@ class Build(models.Model):
# to show build progress in mrb_section.html
for build in recent_builds:
build.percentDone = build.completeper()
+ build.outcomeText = build.get_outcome_text()
return recent_builds
+ def started(self):
+ """
+ As build variables are only added for a build when its BuildStarted event
+ is received, a build with no build variables is counted as
+ "in preparation" and not properly started yet. This method
+ will return False if a build has no build variables (it never properly
+ started), or True otherwise.
+
+ Note that this is a temporary workaround for the fact that we don't
+ have a fine-grained state variable on a build which would allow us
+ to record "in progress" (BuildStarted received) vs. "in preparation".
+ """
+ variables = Variable.objects.filter(build=self)
+ return len(variables) > 0
+
def completeper(self):
tf = Task.objects.filter(build = self)
tfc = tf.count()
if tfc > 0:
- completeper = tf.exclude(order__isnull=True).count()*100/tfc
+ completeper = tf.exclude(order__isnull=True).count()*100 // tfc
else:
completeper = 0
return completeper
@@ -434,58 +478,62 @@ class Build(models.Model):
eta += ((eta - self.started_on)*(100-completeper))/completeper
return eta
+ def has_images(self):
+ """
+ Returns True if at least one of the targets for this build has an
+ image file associated with it, False otherwise
+ """
+ targets = Target.objects.filter(build_id=self.id)
+ has_images = False
+ for target in targets:
+ if target.has_images():
+ has_images = True
+ break
+ return has_images
+
+ def has_image_recipes(self):
+ """
+ Returns True if a build has any targets which were built from
+ image recipes.
+ """
+ image_recipes = self.get_image_recipes()
+ return len(image_recipes) > 0
+
def get_image_file_extensions(self):
"""
- Get list of file name extensions for images produced by this build
+ Get string of file name extensions for images produced by this build;
+ note that this is the actual list of extensions stored on Target objects
+ for this build, and not the value of IMAGE_FSTYPES.
+
+ Returns comma-separated string, e.g. "vmdk, ext4"
"""
- targets = Target.objects.filter(build_id = self.id)
extensions = []
- # pattern to match against file path for building extension string
- pattern = re.compile('\.([^\.]+?)$')
-
+ targets = Target.objects.filter(build_id = self.id)
for target in targets:
- if (not target.is_image):
+ if not target.is_image:
continue
- target_image_files = Target_Image_File.objects.filter(target_id = target.id)
+ target_image_files = Target_Image_File.objects.filter(
+ target_id=target.id)
for target_image_file in target_image_files:
- file_name = os.path.basename(target_image_file.file_name)
- suffix = ''
-
- continue_matching = True
-
- # incrementally extract the suffix from the file path,
- # checking it against the list of valid suffixes at each
- # step; if the path is stripped of all potential suffix
- # parts without matching a valid suffix, this returns all
- # characters after the first '.' in the file name
- while continue_matching:
- matches = pattern.search(file_name)
-
- if None == matches:
- continue_matching = False
- suffix = re.sub('^\.', '', suffix)
- continue
- else:
- suffix = matches.group(1) + suffix
-
- if suffix in Target_Image_File.SUFFIXES:
- continue_matching = False
- continue
- else:
- # reduce the file name and try to find the next
- # segment from the path which might be part
- # of the suffix
- file_name = re.sub('.' + matches.group(1), '', file_name)
- suffix = '.' + suffix
-
- if not suffix in extensions:
- extensions.append(suffix)
+ extensions.append(target_image_file.suffix)
+
+ extensions = list(set(extensions))
+ extensions.sort()
return ', '.join(extensions)
+ def get_image_fstypes(self):
+ """
+ Get the IMAGE_FSTYPES variable value for this build as a de-duplicated
+ list of image file suffixes.
+ """
+ image_fstypes = Variable.objects.get(
+ build=self, variable_name='IMAGE_FSTYPES').variable_value
+ return list(set(re.split(r' {1,}', image_fstypes)))
+
def get_sorted_target_list(self):
tgts = Target.objects.filter(build_id = self.id).order_by( 'target' );
return( tgts );
@@ -576,49 +624,69 @@ class Build(models.Model):
return target_labels
- def get_current_status(self):
- """
- get the status string from the build request if the build
- has one, or the text for the build outcome if it doesn't
- """
-
- from bldcontrol.models import BuildRequest
-
- build_request = None
+ def get_buildrequest(self):
+ buildrequest = None
if hasattr(self, 'buildrequest'):
- build_request = self.buildrequest
+ buildrequest = self.buildrequest
+ return buildrequest
- if (build_request
- and build_request.state != BuildRequest.REQ_INPROGRESS
- and self.outcome == Build.IN_PROGRESS):
- return self.buildrequest.get_state_display()
+ def is_queued(self):
+ from bldcontrol.models import BuildRequest
+ buildrequest = self.get_buildrequest()
+ if buildrequest:
+ return buildrequest.state == BuildRequest.REQ_QUEUED
else:
- return self.get_outcome_text()
+ return False
- def __str__(self):
- return "%d %s %s" % (self.id, self.project, ",".join([t.target for t in self.target_set.all()]))
+ def is_cancelling(self):
+ from bldcontrol.models import BuildRequest
+ buildrequest = self.get_buildrequest()
+ if buildrequest:
+ return self.outcome == Build.IN_PROGRESS and \
+ buildrequest.state == BuildRequest.REQ_CANCELLING
+ else:
+ return False
+ def is_parsing(self):
+ """
+ True if the build is still parsing recipes
+ """
+ return self.outcome == Build.IN_PROGRESS and \
+ self.recipes_parsed < self.recipes_to_parse
-# an Artifact is anything that results from a Build, and may be of interest to the user, and is not stored elsewhere
-class BuildArtifact(models.Model):
- build = models.ForeignKey(Build)
- file_name = models.FilePathField()
- file_size = models.IntegerField()
+ def is_starting(self):
+ """
+ True if the build has no completed tasks yet and is still just starting
+ tasks.
- def get_local_file_name(self):
- try:
- deploydir = Variable.objects.get(build = self.build, variable_name="DEPLOY_DIR").variable_value
- return self.file_name[len(deploydir)+1:]
- except:
- raise
+ Note that the mechanism for testing whether a Task is "done" is whether
+ its order field is set, as per the completeper() method.
+ """
+ return self.outcome == Build.IN_PROGRESS and \
+ self.task_build.filter(order__isnull=False).count() == 0
- return self.file_name
+ def get_state(self):
+ """
+ Get the state of the build; one of 'Succeeded', 'Failed', 'In Progress',
+ 'Cancelled' (Build outcomes); or 'Queued', 'Cancelling' (states
+ dependent on the BuildRequest state).
- def get_basename(self):
- return os.path.basename(self.file_name)
+ This works around the fact that we have BuildRequest states as well
+ as Build states, but really we just want to know the state of the build.
+ """
+ if self.is_cancelling():
+ return 'Cancelling';
+ elif self.is_queued():
+ return 'Queued'
+ elif self.is_parsing():
+ return 'Parsing'
+ elif self.is_starting():
+ return 'Starting'
+ else:
+ return self.get_outcome_text()
- def is_available(self):
- return self.build.buildrequest.environment.has_artifact(self.file_name)
+ def __str__(self):
+ return "%d %s %s" % (self.id, self.project, ",".join([t.target for t in self.target_set.all()]))
class ProjectTarget(models.Model):
project = models.ForeignKey(Project)
@@ -633,6 +701,7 @@ class Target(models.Model):
is_image = models.BooleanField(default = False)
image_size = models.IntegerField(default=0)
license_manifest_path = models.CharField(max_length=500, null=True)
+ package_manifest_path = models.CharField(max_length=500, null=True)
def package_count(self):
return Target_Installed_Package.objects.filter(target_id__exact=self.id).count()
@@ -640,14 +709,180 @@ class Target(models.Model):
def __unicode__(self):
return self.target
+ def get_similar_targets(self):
+ """
+ Get target sfor the same machine, task and target name
+ (e.g. 'core-image-minimal') from a successful build for this project
+ (but excluding this target).
+
+ Note that we only look for targets built by this project because
+ projects can have different configurations from each other, and put
+ their artifacts in different directories.
+
+ The possibility of error when retrieving candidate targets
+ is minimised by the fact that bitbake will rebuild artifacts if MACHINE
+ (or various other variables) change. In this case, there is no need to
+ clone artifacts from another target, as those artifacts will have
+ been re-generated for this target anyway.
+ """
+ query = ~Q(pk=self.pk) & \
+ Q(target=self.target) & \
+ Q(build__machine=self.build.machine) & \
+ Q(build__outcome=Build.SUCCEEDED) & \
+ Q(build__project=self.build.project)
+
+ return Target.objects.filter(query)
+
+ def get_similar_target_with_image_files(self):
+ """
+ Get the most recent similar target with Target_Image_Files associated
+ with it, for the purpose of cloning those files onto this target.
+ """
+ similar_target = None
+
+ candidates = self.get_similar_targets()
+ if candidates.count() == 0:
+ return similar_target
+
+ task_subquery = Q(task=self.task)
+
+ # we can look for a 'build' task if this task is a 'populate_sdk_ext'
+ # task, as the latter also creates images; and vice versa; note that
+ # 'build' targets can have their task set to '';
+ # also note that 'populate_sdk' does not produce image files
+ image_tasks = [
+ '', # aka 'build'
+ 'build',
+ 'image',
+ 'populate_sdk_ext'
+ ]
+ if self.task in image_tasks:
+ task_subquery = Q(task__in=image_tasks)
+
+ # annotate with the count of files, to exclude any targets which
+ # don't have associated files
+ candidates = candidates.annotate(num_files=Count('target_image_file'))
+
+ query = task_subquery & Q(num_files__gt=0)
+
+ candidates = candidates.filter(query)
+
+ if candidates.count() > 0:
+ candidates.order_by('build__completed_on')
+ similar_target = candidates.last()
+
+ return similar_target
+
+ def get_similar_target_with_sdk_files(self):
+ """
+ Get the most recent similar target with TargetSDKFiles associated
+ with it, for the purpose of cloning those files onto this target.
+ """
+ similar_target = None
+
+ candidates = self.get_similar_targets()
+ if candidates.count() == 0:
+ return similar_target
+
+ # annotate with the count of files, to exclude any targets which
+ # don't have associated files
+ candidates = candidates.annotate(num_files=Count('targetsdkfile'))
+
+ query = Q(task=self.task) & Q(num_files__gt=0)
+
+ candidates = candidates.filter(query)
+
+ if candidates.count() > 0:
+ candidates.order_by('build__completed_on')
+ similar_target = candidates.last()
+
+ return similar_target
+
+ def clone_image_artifacts_from(self, target):
+ """
+ Make clones of the Target_Image_Files and TargetKernelFile objects
+ associated with Target target, then associate them with this target.
+
+ Note that for Target_Image_Files, we only want files from the previous
+ build whose suffix matches one of the suffixes defined in this
+ target's build's IMAGE_FSTYPES configuration variable. This prevents the
+ Target_Image_File object for an ext4 image being associated with a
+ target for a project which didn't produce an ext4 image (for example).
+
+ Also sets the license_manifest_path and package_manifest_path
+ of this target to the same path as that of target being cloned from, as
+ the manifests are also build artifacts but are treated differently.
+ """
+
+ image_fstypes = self.build.get_image_fstypes()
+
+ # filter out any image files whose suffixes aren't in the
+ # IMAGE_FSTYPES suffixes variable for this target's build
+ image_files = [target_image_file \
+ for target_image_file in target.target_image_file_set.all() \
+ if target_image_file.suffix in image_fstypes]
+
+ for image_file in image_files:
+ image_file.pk = None
+ image_file.target = self
+ image_file.save()
+
+ kernel_files = target.targetkernelfile_set.all()
+ for kernel_file in kernel_files:
+ kernel_file.pk = None
+ kernel_file.target = self
+ kernel_file.save()
+
+ self.license_manifest_path = target.license_manifest_path
+ self.package_manifest_path = target.package_manifest_path
+ self.save()
+
+ def clone_sdk_artifacts_from(self, target):
+ """
+ Clone TargetSDKFile objects from target and associate them with this
+ target.
+ """
+ sdk_files = target.targetsdkfile_set.all()
+ for sdk_file in sdk_files:
+ sdk_file.pk = None
+ sdk_file.target = self
+ sdk_file.save()
+
+ def has_images(self):
+ """
+ Returns True if this target has one or more image files attached to it.
+ """
+ return self.target_image_file_set.all().count() > 0
+
+# kernel artifacts for a target: bzImage and modules*
+class TargetKernelFile(models.Model):
+ target = models.ForeignKey(Target)
+ file_name = models.FilePathField()
+ file_size = models.IntegerField()
+
+ @property
+ def basename(self):
+ return os.path.basename(self.file_name)
+
+# SDK artifacts for a target: sh and manifest files
+class TargetSDKFile(models.Model):
+ target = models.ForeignKey(Target)
+ file_name = models.FilePathField()
+ file_size = models.IntegerField()
+
+ @property
+ def basename(self):
+ return os.path.basename(self.file_name)
+
class Target_Image_File(models.Model):
# valid suffixes for image files produced by a build
SUFFIXES = {
'btrfs', 'cpio', 'cpio.gz', 'cpio.lz4', 'cpio.lzma', 'cpio.xz',
'cramfs', 'elf', 'ext2', 'ext2.bz2', 'ext2.gz', 'ext2.lzma', 'ext4',
- 'ext4.gz', 'ext3', 'ext3.gz', 'hddimg', 'iso', 'jffs2', 'jffs2.sum',
- 'squashfs', 'squashfs-lzo', 'squashfs-xz', 'tar.bz2', 'tar.lz4',
- 'tar.xz', 'tartar.gz', 'ubi', 'ubifs', 'vmdk'
+ 'ext4.gz', 'ext3', 'ext3.gz', 'hdddirect', 'hddimg', 'iso', 'jffs2',
+ 'jffs2.sum', 'multiubi', 'qcow2', 'squashfs', 'squashfs-lzo',
+ 'squashfs-xz', 'tar', 'tar.bz2', 'tar.gz', 'tar.lz4', 'tar.xz', 'ubi',
+ 'ubifs', 'vdi', 'vmdk', 'wic', 'wic.bz2', 'wic.gz', 'wic.lzma'
}
target = models.ForeignKey(Target)
@@ -656,6 +891,13 @@ class Target_Image_File(models.Model):
@property
def suffix(self):
+ """
+ Suffix for image file, minus leading "."
+ """
+ for suffix in Target_Image_File.SUFFIXES:
+ if self.file_name.endswith(suffix):
+ return suffix
+
filename, suffix = os.path.splitext(self.file_name)
suffix = suffix.lstrip('.')
return suffix
@@ -860,31 +1102,70 @@ class CustomImagePackage(Package):
related_name='appends_set')
-
class Package_DependencyManager(models.Manager):
use_for_related_fields = True
+ TARGET_LATEST = "use-latest-target-for-target"
def get_queryset(self):
return super(Package_DependencyManager, self).get_queryset().exclude(package_id = F('depends_on__id'))
- def get_total_source_deps_size(self):
- """ Returns the total file size of all the packages that depend on
- thispackage.
- """
- return self.all().aggregate(Sum('depends_on__size'))
+ def for_target_or_none(self, target):
+ """ filter the dependencies to be displayed by the supplied target
+ if no dependences are found for the target then try None as the target
+ which will return the dependences calculated without the context of a
+ target e.g. non image recipes.
- def get_total_revdeps_size(self):
- """ Returns the total file size of all the packages that depend on
- this package.
+ returns: { size, packages }
"""
- return self.all().aggregate(Sum('package_id__size'))
+ package_dependencies = self.all_depends().order_by('depends_on__name')
+
+ if target is self.TARGET_LATEST:
+ installed_deps =\
+ package_dependencies.filter(~Q(target__target=None))
+ else:
+ installed_deps =\
+ package_dependencies.filter(Q(target__target=target))
+
+ packages_list = None
+ total_size = 0
+
+ # If we have installed depdencies for this package and target then use
+ # these to display
+ if installed_deps.count() > 0:
+ packages_list = installed_deps
+ total_size = installed_deps.aggregate(
+ Sum('depends_on__size'))['depends_on__size__sum']
+ else:
+ new_list = []
+ package_names = []
+ # Find dependencies for the package that we know about even if
+ # it's not installed on a target e.g. from a non-image recipe
+ for p in package_dependencies.filter(Q(target=None)):
+ if p.depends_on.name in package_names:
+ continue
+ else:
+ package_names.append(p.depends_on.name)
+ new_list.append(p.pk)
+ # while we're here we may as well total up the size to
+ # avoid iterating again
+ total_size += p.depends_on.size
+
+ # We want to return a queryset here for consistency so pick the
+ # deps from the new_list
+ packages_list = package_dependencies.filter(Q(pk__in=new_list))
+
+ return {'packages': packages_list,
+ 'size': total_size}
def all_depends(self):
- """ Returns just the depends packages and not any other dep_type """
+ """ Returns just the depends packages and not any other dep_type
+ Note that this is for any target
+ """
return self.filter(Q(dep_type=Package_Dependency.TYPE_RDEPENDS) |
Q(dep_type=Package_Dependency.TYPE_TRDEPENDS))
+
class Package_Dependency(models.Model):
TYPE_RDEPENDS = 0
TYPE_TRDEPENDS = 1
@@ -930,21 +1211,27 @@ class Target_Installed_Package(models.Model):
target = models.ForeignKey(Target)
package = models.ForeignKey(Package, related_name='buildtargetlist_package')
+
class Package_File(models.Model):
package = models.ForeignKey(Package, related_name='buildfilelist_package')
path = models.FilePathField(max_length=255, blank=True)
size = models.IntegerField()
+
class Recipe(models.Model):
- search_allowed_fields = ['name', 'version', 'file_path', 'section', 'summary', 'description', 'license', 'layer_version__layer__name', 'layer_version__branch', 'layer_version__commit', 'layer_version__local_path', 'layer_version__layer_source__name']
+ search_allowed_fields = ['name', 'version', 'file_path', 'section',
+ 'summary', 'description', 'license',
+ 'layer_version__layer__name',
+ 'layer_version__branch', 'layer_version__commit',
+ 'layer_version__local_path',
+ 'layer_version__layer_source']
- layer_source = models.ForeignKey('LayerSource', default = None, null = True) # from where did we get this recipe
- up_id = models.IntegerField(null = True, default = None) # id of entry in the source
- up_date = models.DateTimeField(null = True, default = None)
+ up_date = models.DateTimeField(null=True, default=None)
- name = models.CharField(max_length=100, blank=True) # pn
- version = models.CharField(max_length=100, blank=True) # pv
- layer_version = models.ForeignKey('Layer_Version', related_name='recipe_layer_version')
+ name = models.CharField(max_length=100, blank=True)
+ version = models.CharField(max_length=100, blank=True)
+ layer_version = models.ForeignKey('Layer_Version',
+ related_name='recipe_layer_version')
summary = models.TextField(blank=True)
description = models.TextField(blank=True)
section = models.CharField(max_length=100, blank=True)
@@ -955,13 +1242,6 @@ class Recipe(models.Model):
pathflags = models.CharField(max_length=200, blank=True)
is_image = models.BooleanField(default=False)
- def get_layersource_view_url(self):
- if self.layer_source is None:
- return ""
-
- url = self.layer_source.get_object_view(self.layer_version.up_branch, "recipes", self.name)
- return url
-
def __unicode__(self):
return "Recipe " + self.name + ":" + self.version
@@ -1007,8 +1287,6 @@ class Recipe_Dependency(models.Model):
class Machine(models.Model):
search_allowed_fields = ["name", "description", "layer_version__layer__name"]
- layer_source = models.ForeignKey('LayerSource', default = None, null = True) # from where did we get this machine
- up_id = models.IntegerField(null = True, default = None) # id of entry in the source
up_date = models.DateTimeField(null = True, default = None)
layer_version = models.ForeignKey('Layer_Version')
@@ -1023,285 +1301,9 @@ class Machine(models.Model):
def __unicode__(self):
return "Machine " + self.name + "(" + self.description + ")"
- class Meta:
- unique_together = ("layer_source", "up_id")
-
-
-from django.db.models.base import ModelBase
-
-class InheritanceMetaclass(ModelBase):
- def __call__(cls, *args, **kwargs):
- obj = super(InheritanceMetaclass, cls).__call__(*args, **kwargs)
- return obj.get_object()
-
-
-class LayerSource(models.Model):
- __metaclass__ = InheritanceMetaclass
-
- class Meta:
- unique_together = (('sourcetype', 'apiurl'), )
-
- TYPE_LOCAL = 0
- TYPE_LAYERINDEX = 1
- TYPE_IMPORTED = 2
- SOURCE_TYPE = (
- (TYPE_LOCAL, "local"),
- (TYPE_LAYERINDEX, "layerindex"),
- (TYPE_IMPORTED, "imported"),
- )
-
- name = models.CharField(max_length=63, unique = True)
- sourcetype = models.IntegerField(choices=SOURCE_TYPE)
- apiurl = models.CharField(max_length=255, null=True, default=None)
-
- def __init__(self, *args, **kwargs):
- super(LayerSource, self).__init__(*args, **kwargs)
- if self.sourcetype == LayerSource.TYPE_LOCAL:
- self.__class__ = LocalLayerSource
- elif self.sourcetype == LayerSource.TYPE_LAYERINDEX:
- self.__class__ = LayerIndexLayerSource
- elif self.sourcetype == LayerSource.TYPE_IMPORTED:
- self.__class__ = ImportedLayerSource
- elif self.sourcetype == None:
- raise Exception("Unknown LayerSource-derived class. If you added a new layer source type, fill out all code stubs.")
-
-
- def update(self):
- """
- Updates the local database information from the upstream layer source
- """
- raise Exception("Abstract, update() must be implemented by all LayerSource-derived classes (object is %s)" % str(vars(self)))
-
- def save(self, *args, **kwargs):
- return super(LayerSource, self).save(*args, **kwargs)
-
- def get_object(self):
- # preset an un-initilized object
- if None == self.name:
- self.name=""
- if None == self.apiurl:
- self.apiurl=""
- if None == self.sourcetype:
- self.sourcetype=LayerSource.TYPE_LOCAL
-
- if self.sourcetype == LayerSource.TYPE_LOCAL:
- self.__class__ = LocalLayerSource
- elif self.sourcetype == LayerSource.TYPE_LAYERINDEX:
- self.__class__ = LayerIndexLayerSource
- elif self.sourcetype == LayerSource.TYPE_IMPORTED:
- self.__class__ = ImportedLayerSource
- else:
- raise Exception("Unknown LayerSource type. If you added a new layer source type, fill out all code stubs.")
- return self
-
- def __unicode__(self):
- return "%s (%s)" % (self.name, self.sourcetype)
-
-
-class LocalLayerSource(LayerSource):
- class Meta(LayerSource._meta.__class__):
- proxy = True
-
- def __init__(self, *args, **kwargs):
- super(LocalLayerSource, self).__init__(args, kwargs)
- self.sourcetype = LayerSource.TYPE_LOCAL
-
- def update(self):
- """
- Fetches layer, recipe and machine information from local repository
- """
- pass
-
-class ImportedLayerSource(LayerSource):
- class Meta(LayerSource._meta.__class__):
- proxy = True
-
- def __init__(self, *args, **kwargs):
- super(ImportedLayerSource, self).__init__(args, kwargs)
- self.sourcetype = LayerSource.TYPE_IMPORTED
-
- def update(self):
- """
- Fetches layer, recipe and machine information from local repository
- """
- pass
-
-
-class LayerIndexLayerSource(LayerSource):
- class Meta(LayerSource._meta.__class__):
- proxy = True
- def __init__(self, *args, **kwargs):
- super(LayerIndexLayerSource, self).__init__(args, kwargs)
- self.sourcetype = LayerSource.TYPE_LAYERINDEX
-
- def get_object_view(self, branch, objectype, upid):
- return self.apiurl + "../branch/" + branch.name + "/" + objectype + "/?q=" + str(upid)
- def update(self):
- """
- Fetches layer, recipe and machine information from remote repository
- """
- assert self.apiurl is not None
- from django.db import transaction, connection
- import urllib2, urlparse, json
- import os
- proxy_settings = os.environ.get("http_proxy", None)
- oe_core_layer = 'openembedded-core'
-
- def _get_json_response(apiurl = self.apiurl):
- _parsedurl = urlparse.urlparse(apiurl)
- path = _parsedurl.path
-
- try:
- res = urllib2.urlopen(apiurl)
- except urllib2.URLError as e:
- raise Exception("Failed to read %s: %s" % (path, e.reason))
-
- return json.loads(res.read())
-
- # verify we can get the basic api
- try:
- apilinks = _get_json_response()
- except Exception as e:
- import traceback
- if proxy_settings is not None:
- logger.info("EE: Using proxy %s" % proxy_settings)
- logger.warning("EE: could not connect to %s, skipping update: %s\n%s" % (self.apiurl, e, traceback.format_exc(e)))
- return
-
- # update branches; only those that we already have names listed in the
- # Releases table
- whitelist_branch_names = map(lambda x: x.branch_name, Release.objects.all())
- if len(whitelist_branch_names) == 0:
- raise Exception("Failed to make list of branches to fetch")
-
- logger.debug("Fetching branches")
- branches_info = _get_json_response(apilinks['branches']
- + "?filter=name:%s" % "OR".join(whitelist_branch_names))
- for bi in branches_info:
- b, created = Branch.objects.get_or_create(layer_source = self, name = bi['name'])
- b.up_id = bi['id']
- b.up_date = bi['updated']
- b.name = bi['name']
- b.short_description = bi['short_description']
- b.save()
-
- # update layers
- layers_info = _get_json_response(apilinks['layerItems'])
-
- for li in layers_info:
- # Special case for the openembedded-core layer
- if li['name'] == oe_core_layer:
- try:
- # If we have an existing openembedded-core for example
- # from the toasterconf.json augment the info using the
- # layerindex rather than duplicate it
- oe_core_l = Layer.objects.get(name=oe_core_layer)
- # Take ownership of the layer as now coming from the
- # layerindex
- oe_core_l.layer_source = self
- oe_core_l.up_id = li['id']
- oe_core_l.summary = li['summary']
- oe_core_l.description = li['description']
- oe_core_l.save()
- continue
-
- except Layer.DoesNotExist:
- pass
-
- l, created = Layer.objects.get_or_create(layer_source = self, name = li['name'])
- l.up_id = li['id']
- l.up_date = li['updated']
- l.vcs_url = li['vcs_url']
- l.vcs_web_url = li['vcs_web_url']
- l.vcs_web_tree_base_url = li['vcs_web_tree_base_url']
- l.vcs_web_file_base_url = li['vcs_web_file_base_url']
- l.summary = li['summary']
- l.description = li['description']
- l.save()
-
- # update layerbranches/layer_versions
- logger.debug("Fetching layer information")
- layerbranches_info = _get_json_response(apilinks['layerBranches']
- + "?filter=branch:%s" % "OR".join(map(lambda x: str(x.up_id), [i for i in Branch.objects.filter(layer_source = self) if i.up_id is not None] ))
- )
-
- for lbi in layerbranches_info:
- lv, created = Layer_Version.objects.get_or_create(layer_source = self,
- up_id = lbi['id'],
- layer=Layer.objects.get(layer_source = self, up_id = lbi['layer'])
- )
-
- lv.up_date = lbi['updated']
- lv.up_branch = Branch.objects.get(layer_source = self, up_id = lbi['branch'])
- lv.branch = lbi['actual_branch']
- lv.commit = lbi['actual_branch']
- lv.dirpath = lbi['vcs_subdir']
- lv.save()
-
- # update layer dependencies
- layerdependencies_info = _get_json_response(apilinks['layerDependencies'])
- dependlist = {}
- for ldi in layerdependencies_info:
- try:
- lv = Layer_Version.objects.get(layer_source = self, up_id = ldi['layerbranch'])
- except Layer_Version.DoesNotExist as e:
- continue
-
- if lv not in dependlist:
- dependlist[lv] = []
- try:
- dependlist[lv].append(Layer_Version.objects.get(layer_source = self, layer__up_id = ldi['dependency'], up_branch = lv.up_branch))
- except Layer_Version.DoesNotExist:
- logger.warning("Cannot find layer version (ls:%s), up_id:%s lv:%s" % (self, ldi['dependency'], lv))
-
- for lv in dependlist:
- LayerVersionDependency.objects.filter(layer_version = lv).delete()
- for lvd in dependlist[lv]:
- LayerVersionDependency.objects.get_or_create(layer_version = lv, depends_on = lvd)
-
-
- # update machines
- logger.debug("Fetching machine information")
- machines_info = _get_json_response(apilinks['machines']
- + "?filter=layerbranch:%s" % "OR".join(map(lambda x: str(x.up_id), Layer_Version.objects.filter(layer_source = self)))
- )
-
- for mi in machines_info:
- mo, created = Machine.objects.get_or_create(layer_source = self, up_id = mi['id'], layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch']))
- mo.up_date = mi['updated']
- mo.name = mi['name']
- mo.description = mi['description']
- mo.save()
-
- # update recipes; paginate by layer version / layer branch
- logger.debug("Fetching target information")
- recipes_info = _get_json_response(apilinks['recipes']
- + "?filter=layerbranch:%s" % "OR".join(map(lambda x: str(x.up_id), Layer_Version.objects.filter(layer_source = self)))
- )
- for ri in recipes_info:
- try:
- ro, created = Recipe.objects.get_or_create(layer_source = self, up_id = ri['id'], layer_version = Layer_Version.objects.get(layer_source = self, up_id = ri['layerbranch']))
- ro.up_date = ri['updated']
- ro.name = ri['pn']
- ro.version = ri['pv']
- ro.summary = ri['summary']
- ro.description = ri['description']
- ro.section = ri['section']
- ro.license = ri['license']
- ro.homepage = ri['homepage']
- ro.bugtracker = ri['bugtracker']
- ro.file_path = ri['filepath'] + "/" + ri['filename']
- if 'inherits' in ri:
- ro.is_image = 'image' in ri['inherits'].split()
- else: # workaround for old style layer index
- ro.is_image = "-image-" in ri['pn']
- ro.save()
- except IntegrityError as e:
- logger.debug("Failed saving recipe, ignoring: %s (%s:%s)" % (e, ro.layer_version, ri['filepath']+"/"+ri['filename']))
- ro.delete()
class BitbakeVersion(models.Model):
@@ -1325,87 +1327,94 @@ class Release(models.Model):
def __unicode__(self):
return "%s (%s)" % (self.name, self.branch_name)
-class ReleaseLayerSourcePriority(models.Model):
- """ Each release selects layers from the set up layer sources, ordered by priority """
- release = models.ForeignKey("Release")
- layer_source = models.ForeignKey("LayerSource")
- priority = models.IntegerField(default = 0)
-
- def __unicode__(self):
- return "%s-%s:%d" % (self.release.name, self.layer_source.name, self.priority)
- class Meta:
- unique_together = (('release', 'layer_source'),)
-
+ def __str__(self):
+ return self.name
class ReleaseDefaultLayer(models.Model):
release = models.ForeignKey(Release)
layer_name = models.CharField(max_length=100, default="")
-# Branch class is synced with layerindex.Branch, branches can only come from remote layer indexes
-class Branch(models.Model):
- layer_source = models.ForeignKey('LayerSource', null = True, default = True)
- up_id = models.IntegerField(null = True, default = None) # id of branch in the source
- up_date = models.DateTimeField(null = True, default = None)
-
- name = models.CharField(max_length=50)
- short_description = models.CharField(max_length=50, blank=True)
+class LayerSource(object):
+ """ Where the layer metadata came from """
+ TYPE_LOCAL = 0
+ TYPE_LAYERINDEX = 1
+ TYPE_IMPORTED = 2
+ TYPE_BUILD = 3
- class Meta:
- verbose_name_plural = "Branches"
- unique_together = (('layer_source', 'name'),('layer_source', 'up_id'))
+ SOURCE_TYPE = (
+ (TYPE_LOCAL, "local"),
+ (TYPE_LAYERINDEX, "layerindex"),
+ (TYPE_IMPORTED, "imported"),
+ (TYPE_BUILD, "build"),
+ )
- def __unicode__(self):
- return self.name
+ def types_dict():
+ """ Turn the TYPES enums into a simple dictionary """
+ dictionary = {}
+ for key in LayerSource.__dict__:
+ if "TYPE" in key:
+ dictionary[key] = getattr(LayerSource, key)
+ return dictionary
-# Layer class synced with layerindex.LayerItem
class Layer(models.Model):
- layer_source = models.ForeignKey(LayerSource, null = True, default = None) # from where did we got this layer
- up_id = models.IntegerField(null = True, default = None) # id of layer in the remote source
- up_date = models.DateTimeField(null = True, default = None)
+
+ up_date = models.DateTimeField(null=True, default=timezone.now)
name = models.CharField(max_length=100)
layer_index_url = models.URLField()
- vcs_url = GitURLField(default = None, null = True)
- vcs_web_url = models.URLField(null = True, default = None)
- vcs_web_tree_base_url = models.URLField(null = True, default = None)
- vcs_web_file_base_url = models.URLField(null = True, default = None)
+ vcs_url = GitURLField(default=None, null=True)
+ local_source_dir = models.TextField(null = True, default = None)
+ vcs_web_url = models.URLField(null=True, default=None)
+ vcs_web_tree_base_url = models.URLField(null=True, default=None)
+ vcs_web_file_base_url = models.URLField(null=True, default=None)
- summary = models.TextField(help_text='One-line description of the layer', null = True, default = None)
- description = models.TextField(null = True, default = None)
+ summary = models.TextField(help_text='One-line description of the layer',
+ null=True, default=None)
+ description = models.TextField(null=True, default=None)
def __unicode__(self):
- return "%s / %s " % (self.name, self.layer_source)
-
- class Meta:
- unique_together = (("layer_source", "up_id"), ("layer_source", "name"))
+ return "%s / %s " % (self.name, self.summary)
-# LayerCommit class is synced with layerindex.LayerBranch
class Layer_Version(models.Model):
"""
A Layer_Version either belongs to a single project or no project
"""
- search_allowed_fields = ["layer__name", "layer__summary", "layer__description", "layer__vcs_url", "dirpath", "up_branch__name", "commit", "branch"]
- build = models.ForeignKey(Build, related_name='layer_version_build', default = None, null = True)
+ search_allowed_fields = ["layer__name", "layer__summary",
+ "layer__description", "layer__vcs_url",
+ "dirpath", "release__name", "commit", "branch"]
+
+ build = models.ForeignKey(Build, related_name='layer_version_build',
+ default=None, null=True)
+
layer = models.ForeignKey(Layer, related_name='layer_version_layer')
- layer_source = models.ForeignKey(LayerSource, null = True, default = None) # from where did we get this Layer Version
- up_id = models.IntegerField(null = True, default = None) # id of layerbranch in the remote source
- up_date = models.DateTimeField(null = True, default = None)
- up_branch = models.ForeignKey(Branch, null = True, default = None)
+ layer_source = models.IntegerField(choices=LayerSource.SOURCE_TYPE,
+ default=0)
+
+ up_date = models.DateTimeField(null=True, default=timezone.now)
- branch = models.CharField(max_length=80) # LayerBranch.actual_branch
- commit = models.CharField(max_length=100) # LayerBranch.vcs_last_rev
- dirpath = models.CharField(max_length=255, null = True, default = None) # LayerBranch.vcs_subdir
- priority = models.IntegerField(default = 0) # if -1, this is a default layer
+ # To which metadata release does this layer version belong to
+ release = models.ForeignKey(Release, null=True, default=None)
- local_path = models.FilePathField(max_length=1024, default = "/") # where this layer was checked-out
+ branch = models.CharField(max_length=80)
+ commit = models.CharField(max_length=100)
+ # If the layer is in a subdir
+ dirpath = models.CharField(max_length=255, null=True, default=None)
- project = models.ForeignKey('Project', null = True, default = None) # Set if this layer is project-specific; always set for imported layers, and project-set branches
+ # if -1, this is a default layer
+ priority = models.IntegerField(default=0)
- # code lifted, with adaptations, from the layerindex-web application https://git.yoctoproject.org/cgit/cgit.cgi/layerindex-web/
+ # where this layer exists on the filesystem
+ local_path = models.FilePathField(max_length=1024, default="/")
+
+ # Set if this layer is restricted to a particular project
+ project = models.ForeignKey('Project', null=True, default=None)
+
+ # code lifted, with adaptations, from the layerindex-web application
+ # https://git.yoctoproject.org/cgit/cgit.cgi/layerindex-web/
def _handle_url_path(self, base_url, path):
import re, posixpath
if base_url:
@@ -1422,7 +1431,7 @@ class Layer_Version(models.Model):
extra_path = self.dirpath
else:
extra_path = path
- branchname = self.up_branch.name
+ branchname = self.release.name
url = base_url.replace('%branch%', branchname)
# If there's a % in the path (e.g. a wildcard bbappend) we need to encode it
@@ -1447,23 +1456,19 @@ class Layer_Version(models.Model):
def get_vcs_file_link_url(self, file_path=""):
if self.layer.vcs_web_file_base_url is None:
return None
- return self._handle_url_path(self.layer.vcs_web_file_base_url, file_path)
+ return self._handle_url_path(self.layer.vcs_web_file_base_url,
+ file_path)
def get_vcs_dirpath_link_url(self):
if self.layer.vcs_web_tree_base_url is None:
return None
return self._handle_url_path(self.layer.vcs_web_tree_base_url, '')
- def get_equivalents_wpriority(self, project):
- layer_versions = project.get_all_compatible_layer_versions()
- filtered = layer_versions.filter(layer__name = self.layer.name)
- return filtered.order_by("-layer_source__releaselayersourcepriority__priority")
-
def get_vcs_reference(self):
if self.branch is not None and len(self.branch) > 0:
return self.branch
- if self.up_branch is not None:
- return self.up_branch.name
+ if self.release is not None:
+ return self.release.name
if self.commit is not None and len(self.commit) > 0:
return self.commit
return 'N/A'
@@ -1491,20 +1496,23 @@ class Layer_Version(models.Model):
return sorted(result, key=lambda x: x.layer.name)
def __unicode__(self):
- return "%d %s (VCS %s, Project %s)" % (self.pk, str(self.layer), self.get_vcs_reference(), self.build.project if self.build is not None else "No project")
+ return ("id %d belongs to layer: %s" % (self.pk, self.layer.name))
- class Meta:
- unique_together = ("layer_source", "up_id")
+ def __str__(self):
+ if self.release:
+ release = self.release.name
+ else:
+ release = "No release set"
-class LayerVersionDependency(models.Model):
- layer_source = models.ForeignKey(LayerSource, null = True, default = None) # from where did we got this layer
- up_id = models.IntegerField(null = True, default = None) # id of layerbranch in the remote source
+ return "%d %s (%s)" % (self.pk, self.layer.name, release)
- layer_version = models.ForeignKey(Layer_Version, related_name="dependencies")
- depends_on = models.ForeignKey(Layer_Version, related_name="dependees")
- class Meta:
- unique_together = ("layer_source", "up_id")
+class LayerVersionDependency(models.Model):
+
+ layer_version = models.ForeignKey(Layer_Version,
+ related_name="dependencies")
+ depends_on = models.ForeignKey(Layer_Version,
+ related_name="dependees")
class ProjectLayer(models.Model):
project = models.ForeignKey(Project)
@@ -1585,6 +1593,21 @@ class CustomImageRecipe(Recipe):
Q(recipe_includes=self)) &
~Q(recipe_excludes=self))
+ def get_base_recipe_file(self):
+ """Get the base recipe file path if it exists on the file system"""
+ path_schema_one = "%s/%s" % (self.base_recipe.layer_version.dirpath,
+ self.base_recipe.file_path)
+
+ path_schema_two = self.base_recipe.file_path
+
+ if os.path.exists(path_schema_one):
+ return path_schema_one
+
+ # The path may now be the full path if the recipe has been built
+ if os.path.exists(path_schema_two):
+ return path_schema_two
+
+ return None
def generate_recipe_file_contents(self):
"""Generate the contents for the recipe file."""
@@ -1599,17 +1622,16 @@ class CustomImageRecipe(Recipe):
# We add all the known packages to be built by this recipe apart
# from locale packages which are are controlled with IMAGE_LINGUAS.
for pkg in self.get_all_packages().exclude(
- name__icontains="locale"):
+ name__icontains="locale"):
packages_conf += pkg.name+' '
packages_conf += "\""
- try:
- base_recipe = open("%s/%s" %
- (self.base_recipe.layer_version.dirpath,
- self.base_recipe.file_path), 'r').read()
- except IOError:
- # The path may now be the full path if the recipe has been built
- base_recipe = open(self.base_recipe.file_path, 'r').read()
+
+ base_recipe_path = self.get_base_recipe_file()
+ if base_recipe_path:
+ base_recipe = open(base_recipe_path, 'r').read()
+ else:
+ raise IOError("Based on recipe file not found")
# Add a special case for when the recipe we have based a custom image
# recipe on requires another recipe.
@@ -1618,8 +1640,8 @@ class CustomImageRecipe(Recipe):
# "require recipes-core/images/core-image-minimal.bb"
req_search = re.search(r'(require\s+)(.+\.bb\s*$)',
- base_recipe,
- re.MULTILINE)
+ base_recipe,
+ re.MULTILINE)
if req_search:
require_filename = req_search.group(2).strip()
@@ -1629,19 +1651,19 @@ class CustomImageRecipe(Recipe):
new_require_line = "require %s" % corrected_location
- base_recipe = \
- base_recipe.replace(req_search.group(0), new_require_line)
-
+ base_recipe = base_recipe.replace(req_search.group(0),
+ new_require_line)
- info = {"date" : timezone.now().strftime("%Y-%m-%d %H:%M:%S"),
- "base_recipe" : base_recipe,
- "recipe_name" : self.name,
- "base_recipe_name" : self.base_recipe.name,
- "license" : self.license,
- "summary" : self.summary,
- "description" : self.description,
- "packages_conf" : packages_conf.strip(),
- }
+ info = {
+ "date": timezone.now().strftime("%Y-%m-%d %H:%M:%S"),
+ "base_recipe": base_recipe,
+ "recipe_name": self.name,
+ "base_recipe_name": self.base_recipe.name,
+ "license": self.license,
+ "summary": self.summary,
+ "description": self.description,
+ "packages_conf": packages_conf.strip()
+ }
recipe_contents = ("# Original recipe %(base_recipe_name)s \n"
"%(base_recipe)s\n\n"
@@ -1717,6 +1739,11 @@ def invalidate_cache(**kwargs):
except Exception as e:
logger.warning("Problem with cache backend: Failed to clear cache: %s" % e)
+def signal_runbuilds():
+ """Send SIGUSR1 to runbuilds process"""
+ with open(os.path.join(os.getenv('BUILDDIR'), '.runbuilds.pid')) as pidf:
+ os.kill(int(pidf.read()), SIGUSR1)
+
django.db.models.signals.post_save.connect(invalidate_cache)
django.db.models.signals.post_delete.connect(invalidate_cache)
django.db.models.signals.m2m_changed.connect(invalidate_cache)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/orm/tests.py b/import-layers/yocto-poky/bitbake/lib/toaster/orm/tests.py
deleted file mode 100644
index 719266e6d..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/orm/tests.py
+++ /dev/null
@@ -1,180 +0,0 @@
-#! /usr/bin/env python
-# ex:ts=4:sw=4:sts=4:et
-# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-#
-# BitBake Toaster Implementation
-#
-# Copyright (C) 2013-2015 Intel Corporation
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-"""Test cases for Toaster ORM."""
-
-from django.test import TestCase, TransactionTestCase
-from orm.models import LocalLayerSource, LayerIndexLayerSource, ImportedLayerSource, LayerSource
-from orm.models import Branch, LayerVersionDependency
-
-from orm.models import Project, Layer, Layer_Version, Branch, ProjectLayer
-from orm.models import Release, ReleaseLayerSourcePriority, BitbakeVersion
-
-from django.db import IntegrityError
-
-import os
-
-# set TTS_LAYER_INDEX to the base url to use a different instance of the layer index
-
-class LayerSourceVerifyInheritanceSaveLoad(TestCase):
- """
- Tests to verify inheritance for the LayerSource proxy-inheritance classes.
- """
- def test_object_creation(self):
- """Test LayerSource object creation."""
- for name, sourcetype in [("a1", LayerSource.TYPE_LOCAL),
- ("a2", LayerSource.TYPE_LAYERINDEX),
- ("a3", LayerSource.TYPE_IMPORTED)]:
- LayerSource.objects.create(name=name, sourcetype=sourcetype)
-
- objects = LayerSource.objects.all()
- self.assertTrue(isinstance(objects[0], LocalLayerSource))
- self.assertTrue(isinstance(objects[1], LayerIndexLayerSource))
- self.assertTrue(isinstance(objects[2], ImportedLayerSource))
-
- def test_duplicate_error(self):
- """Test creation of duplicate LayerSource objects."""
- stype = LayerSource.TYPE_LOCAL
- LayerSource.objects.create(name="a1", sourcetype=stype)
- with self.assertRaises(IntegrityError):
- LayerSource.objects.create(name="a1", sourcetype=stype)
-
-
-class LILSUpdateTestCase(TransactionTestCase):
- """Test Layer Source update."""
-
- def setUp(self):
- """Create release."""
- bbv = BitbakeVersion.objects.create(\
- name="master", giturl="git://git.openembedded.org/bitbake")
- Release.objects.create(name="default-release", bitbake_version=bbv,
- branch_name="master")
-
- def test_update(self):
- """Check if LayerSource.update can fetch branches."""
- url = os.getenv("TTS_LAYER_INDEX",
- default="http://layers.openembedded.org/")
-
- lsobj = LayerSource.objects.create(\
- name="b1", sourcetype=LayerSource.TYPE_LAYERINDEX,
- apiurl=url + "layerindex/api/")
- lsobj.update()
- self.assertTrue(lsobj.branch_set.all().count() > 0,
- "no branches fetched")
-
-class LayerVersionEquivalenceTestCase(TestCase):
- """Verify Layer_Version priority selection."""
-
- def setUp(self):
- """Create required objects."""
- # create layer source
- self.lsrc = LayerSource.objects.create(name="dummy-layersource",
- sourcetype=LayerSource.TYPE_LOCAL)
- # create release
- bbv = BitbakeVersion.objects.create(\
- name="master", giturl="git://git.openembedded.org/bitbake")
- self.release = Release.objects.create(name="default-release",
- bitbake_version=bbv,
- branch_name="master")
- # attach layer source to release
- ReleaseLayerSourcePriority.objects.create(\
- release=self.release, layer_source=self.lsrc, priority=1)
-
- # create a layer version for the layer on the specified branch
- self.layer = Layer.objects.create(name="meta-testlayer",
- layer_source=self.lsrc)
- self.branch = Branch.objects.create(name="master", layer_source=self.lsrc)
- self.lver = Layer_Version.objects.create(\
- layer=self.layer, layer_source=self.lsrc, up_branch=self.branch)
-
- # create project and project layer
- self.project = Project.objects.create_project(name="test-project",
- release=self.release)
- ProjectLayer.objects.create(project=self.project,
- layercommit=self.lver)
-
- # create spoof layer that should not appear in the search results
- layer = Layer.objects.create(name="meta-notvalid",
- layer_source=self.lsrc)
- self.lver2 = Layer_Version.objects.create(layer=layer,
- layer_source=self.lsrc,
- up_branch=self.branch)
-
- def test_single_layersource(self):
- """
- When we have a single layer version,
- get_equivalents_wpriority() should return a list with
- just this layer_version.
- """
- equivqs = self.lver.get_equivalents_wpriority(self.project)
- self.assertEqual(list(equivqs), [self.lver])
-
- def test_dual_layersource(self):
- """
- If we have two layers with the same name, from different layer sources,
- we expect both layers in, in increasing priority of the layer source.
- """
- lsrc2 = LayerSource.objects.create(\
- name="dummy-layersource2",
- sourcetype=LayerSource.TYPE_LOCAL,
- apiurl="test")
-
- # assign a lower priority for the second layer source
- self.release.releaselayersourcepriority_set.create(layer_source=lsrc2,
- priority=2)
-
- # create a new layer_version for a layer with the same name
- # coming from the second layer source
- layer2 = Layer.objects.create(name="meta-testlayer",
- layer_source=lsrc2)
- lver2 = Layer_Version.objects.create(layer=layer2, layer_source=lsrc2,
- up_branch=self.branch)
-
- # expect two layer versions, in the priority order
- equivqs = self.lver.get_equivalents_wpriority(self.project)
- self.assertEqual(list(equivqs), [lver2, self.lver])
-
- def test_compatible_layer_versions(self):
- """
- When we have a 2 layer versions, get_all_compatible_layerversions()
- should return a queryset with both.
- """
- compat_lv = self.project.get_all_compatible_layer_versions()
- self.assertEqual(list(compat_lv), [self.lver, self.lver2])
-
- def test_layerversion_get_alldeps(self):
- """Test Layer_Version.get_alldeps API."""
- lvers = {}
- for i in range(10):
- name = "layer%d" % i
- lvers[name] = Layer_Version.objects.create(layer=Layer.objects.create(name=name),
- project=self.project)
- if i:
- LayerVersionDependency.objects.create(layer_version=lvers["layer%d" % (i - 1)],
- depends_on=lvers[name])
- # Check dinamically added deps
- self.assertEqual(lvers['layer0'].get_alldeps(self.project.id),
- [lvers['layer%d' % n] for n in range(1, i+1)])
-
- # Check chain of deps created in previous loop
- for i in range(10):
- self.assertEqual(lvers['layer%d' % i].get_alldeps(self.project.id),
- [lvers['layer%d' % n] for n in range(i+1, 10)])
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/README b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/README
index 63e8169c1..6b09d20d8 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/README
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/README
@@ -4,15 +4,16 @@ These tests require Selenium to be installed in your Python environment.
The simplest way to install this is via pip:
- pip install selenium
+ pip install selenium==2.53.2
-Alternatively, if you used pip to install the libraries required by Toaster,
-selenium will already be installed.
+Note that if you use other versions of Selenium, some of the tests (such as
+tests.browser.test_js_unit_tests.TestJsUnitTests) may fail, as these rely on
+a Selenium test report with a version-specific format.
To run tests against Chrome:
* Download chromedriver for your host OS from
- https://code.google.com/p/chromedriver/downloads/list
+ https://sites.google.com/a/chromium.org/chromedriver/downloads
* On *nix systems, put chromedriver on PATH
* On Windows, put chromedriver.exe in the same directory as chrome.exe
@@ -23,15 +24,30 @@ To run tests against PhantomJS (headless):
* On *nix systems, put phantomjs on PATH
* Not tested on Windows
-Firefox should work without requiring additional software to be installed.
+To run tests against Firefox, you may need to install the Marionette driver,
+depending on how new your version of Firefox is. One clue that you need to do
+this is if you see an exception like:
-The test case will instantiate a Selenium driver set by the
+ selenium.common.exceptions.WebDriverException: Message: The browser
+ appears to have exited before we could connect. If you specified
+ a log_file in the FirefoxBinary constructor, check it for details.
+
+See https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver
+for installation instructions. Ensure that the Marionette executable (renamed
+as wires on Linux or wires.exe on Windows) is on your PATH; and use "marionette"
+as the browser string passed via TOASTER_TESTS_BROWSER (see below).
+
+(Note: The Toaster tests have been checked against Firefox 47 with the
+Marionette driver.)
+
+The test cases will instantiate a Selenium driver set by the
TOASTER_TESTS_BROWSER environment variable, or Chrome if this is not specified.
Available drivers:
* chrome (default)
* firefox
+* marionette (for newer Firefoxes)
* ie
* phantomjs
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers.py
index 56dbe2b34..08711e455 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers.py
@@ -27,178 +27,8 @@
Helper methods for creating Toaster Selenium tests which run within
the context of Django unit tests.
"""
-
-import os
-import time
-
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
-from selenium import webdriver
-from selenium.webdriver.support.ui import WebDriverWait
-from selenium.common.exceptions import NoSuchElementException, \
- StaleElementReferenceException, TimeoutException
-
-def create_selenium_driver(browser='chrome'):
- # set default browser string based on env (if available)
- env_browser = os.environ.get('TOASTER_TESTS_BROWSER')
- if env_browser:
- browser = env_browser
-
- if browser == 'chrome':
- return webdriver.Chrome(
- service_args=["--verbose", "--log-path=selenium.log"]
- )
- elif browser == 'firefox':
- return webdriver.Firefox()
- elif browser == 'ie':
- return webdriver.Ie()
- elif browser == 'phantomjs':
- return webdriver.PhantomJS()
- else:
- msg = 'Selenium driver for browser %s is not available' % browser
- raise RuntimeError(msg)
-
-class Wait(WebDriverWait):
- """
- Subclass of WebDriverWait with predetermined timeout and poll
- frequency. Also deals with a wider variety of exceptions.
- """
- _TIMEOUT = 10
- _POLL_FREQUENCY = 0.5
-
- def __init__(self, driver):
- super(Wait, self).__init__(driver, self._TIMEOUT, self._POLL_FREQUENCY)
-
- def until(self, method, message=''):
- """
- Calls the method provided with the driver as an argument until the
- return value is not False.
- """
-
- end_time = time.time() + self._timeout
- while True:
- try:
- value = method(self._driver)
- if value:
- return value
- except NoSuchElementException:
- pass
- except StaleElementReferenceException:
- pass
-
- time.sleep(self._poll)
- if time.time() > end_time:
- break
-
- raise TimeoutException(message)
-
- def until_not(self, method, message=''):
- """
- Calls the method provided with the driver as an argument until the
- return value is False.
- """
-
- end_time = time.time() + self._timeout
- while True:
- try:
- value = method(self._driver)
- if not value:
- return value
- except NoSuchElementException:
- return True
- except StaleElementReferenceException:
- pass
-
- time.sleep(self._poll)
- if time.time() > end_time:
- break
-
- raise TimeoutException(message)
-
-class SeleniumTestCase(StaticLiveServerTestCase):
- """
- NB StaticLiveServerTestCase is used as the base test case so that
- static files are served correctly in a Selenium test run context; see
- https://docs.djangoproject.com/en/1.9/ref/contrib/staticfiles/#specialized-test-case-to-support-live-testing
- """
-
- @classmethod
- def setUpClass(cls):
- """ Create a webdriver driver at the class level """
-
- super(SeleniumTestCase, cls).setUpClass()
-
- # instantiate the Selenium webdriver once for all the test methods
- # in this test case
- cls.driver = create_selenium_driver()
-
- @classmethod
- def tearDownClass(cls):
- """ Clean up webdriver driver """
-
- cls.driver.quit()
- super(SeleniumTestCase, cls).tearDownClass()
-
- def get(self, url):
- """
- Selenium requires absolute URLs, so convert Django URLs returned
- by resolve() or similar to absolute ones and get using the
- webdriver instance.
-
- url: a relative URL
- """
- abs_url = '%s%s' % (self.live_server_url, url)
- self.driver.get(abs_url)
-
- def find(self, selector):
- """ Find single element by CSS selector """
- return self.driver.find_element_by_css_selector(selector)
-
- def find_all(self, selector):
- """ Find all elements matching CSS selector """
- return self.driver.find_elements_by_css_selector(selector)
-
- def focused_element(self):
- """ Return the element which currently has focus on the page """
- return self.driver.switch_to.active_element
-
- def wait_until_present(self, selector):
- """ Wait until element matching CSS selector is on the page """
- is_present = lambda driver: self.find(selector)
- msg = 'An element matching "%s" should be on the page' % selector
- element = Wait(self.driver).until(is_present, msg)
- return element
-
- def wait_until_visible(self, selector):
- """ Wait until element matching CSS selector is visible on the page """
- is_visible = lambda driver: self.find(selector).is_displayed()
- msg = 'An element matching "%s" should be visible' % selector
- Wait(self.driver).until(is_visible, msg)
- return self.find(selector)
-
- def wait_until_focused(self, selector):
- """ Wait until element matching CSS selector has focus """
- is_focused = \
- lambda driver: self.find(selector) == self.focused_element()
- msg = 'An element matching "%s" should be focused' % selector
- Wait(self.driver).until(is_focused, msg)
- return self.find(selector)
-
- def enter_text(self, selector, value):
- """ Insert text into element matching selector """
- # note that keyup events don't occur until the element is clicked
- # (in the case of <input type="text"...>, for example), so simulate
- # user clicking the element before inserting text into it
- field = self.click(selector)
-
- field.send_keys(value)
- return field
-
- def click(self, selector):
- """ Click on element which matches CSS selector """
- element = self.wait_until_visible(selector)
- element.click()
- return element
+from tests.browser.selenium_helpers_base import SeleniumTestCaseBase
- def get_page_source(self):
- """ Get raw HTML for the current page """
- return self.driver.page_source
+class SeleniumTestCase(SeleniumTestCaseBase, StaticLiveServerTestCase):
+ pass
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py
new file mode 100644
index 000000000..14e9c1564
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py
@@ -0,0 +1,218 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The Wait class and some of SeleniumDriverHelper and SeleniumTestCase are
+# modified from Patchwork, released under the same licence terms as Toaster:
+# https://github.com/dlespiau/patchwork/blob/master/patchwork/tests.browser.py
+
+"""
+Helper methods for creating Toaster Selenium tests which run within
+the context of Django unit tests.
+"""
+
+import os
+import time
+import unittest
+
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
+from selenium import webdriver
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
+from selenium.common.exceptions import NoSuchElementException, \
+ StaleElementReferenceException, TimeoutException
+
+def create_selenium_driver(browser='chrome'):
+ # set default browser string based on env (if available)
+ env_browser = os.environ.get('TOASTER_TESTS_BROWSER')
+ if env_browser:
+ browser = env_browser
+
+ if browser == 'chrome':
+ return webdriver.Chrome(
+ service_args=["--verbose", "--log-path=selenium.log"]
+ )
+ elif browser == 'firefox':
+ return webdriver.Firefox()
+ elif browser == 'marionette':
+ capabilities = DesiredCapabilities.FIREFOX
+ capabilities['marionette'] = True
+ return webdriver.Firefox(capabilities=capabilities)
+ elif browser == 'ie':
+ return webdriver.Ie()
+ elif browser == 'phantomjs':
+ return webdriver.PhantomJS()
+ else:
+ msg = 'Selenium driver for browser %s is not available' % browser
+ raise RuntimeError(msg)
+
+class Wait(WebDriverWait):
+ """
+ Subclass of WebDriverWait with predetermined timeout and poll
+ frequency. Also deals with a wider variety of exceptions.
+ """
+ _TIMEOUT = 10
+ _POLL_FREQUENCY = 0.5
+
+ def __init__(self, driver):
+ super(Wait, self).__init__(driver, self._TIMEOUT, self._POLL_FREQUENCY)
+
+ def until(self, method, message=''):
+ """
+ Calls the method provided with the driver as an argument until the
+ return value is not False.
+ """
+
+ end_time = time.time() + self._timeout
+ while True:
+ try:
+ value = method(self._driver)
+ if value:
+ return value
+ except NoSuchElementException:
+ pass
+ except StaleElementReferenceException:
+ pass
+
+ time.sleep(self._poll)
+ if time.time() > end_time:
+ break
+
+ raise TimeoutException(message)
+
+ def until_not(self, method, message=''):
+ """
+ Calls the method provided with the driver as an argument until the
+ return value is False.
+ """
+
+ end_time = time.time() + self._timeout
+ while True:
+ try:
+ value = method(self._driver)
+ if not value:
+ return value
+ except NoSuchElementException:
+ return True
+ except StaleElementReferenceException:
+ pass
+
+ time.sleep(self._poll)
+ if time.time() > end_time:
+ break
+
+ raise TimeoutException(message)
+
+class SeleniumTestCaseBase(unittest.TestCase):
+ """
+ NB StaticLiveServerTestCase is used as the base test case so that
+ static files are served correctly in a Selenium test run context; see
+ https://docs.djangoproject.com/en/1.9/ref/contrib/staticfiles/#specialized-test-case-to-support-live-testing
+ """
+
+ @classmethod
+ def setUpClass(cls):
+ """ Create a webdriver driver at the class level """
+
+ super(SeleniumTestCaseBase, cls).setUpClass()
+
+ # instantiate the Selenium webdriver once for all the test methods
+ # in this test case
+ cls.driver = create_selenium_driver()
+ cls.driver.maximize_window()
+
+ @classmethod
+ def tearDownClass(cls):
+ """ Clean up webdriver driver """
+
+ cls.driver.quit()
+ super(SeleniumTestCaseBase, cls).tearDownClass()
+
+ def get(self, url):
+ """
+ Selenium requires absolute URLs, so convert Django URLs returned
+ by resolve() or similar to absolute ones and get using the
+ webdriver instance.
+
+ url: a relative URL
+ """
+ abs_url = '%s%s' % (self.live_server_url, url)
+ self.driver.get(abs_url)
+
+ def find(self, selector):
+ """ Find single element by CSS selector """
+ return self.driver.find_element_by_css_selector(selector)
+
+ def find_all(self, selector):
+ """ Find all elements matching CSS selector """
+ return self.driver.find_elements_by_css_selector(selector)
+
+ def element_exists(self, selector):
+ """
+ Return True if one element matching selector exists,
+ False otherwise
+ """
+ return len(self.find_all(selector)) == 1
+
+ def focused_element(self):
+ """ Return the element which currently has focus on the page """
+ return self.driver.switch_to.active_element
+
+ def wait_until_present(self, selector):
+ """ Wait until element matching CSS selector is on the page """
+ is_present = lambda driver: self.find(selector)
+ msg = 'An element matching "%s" should be on the page' % selector
+ element = Wait(self.driver).until(is_present, msg)
+ return element
+
+ def wait_until_visible(self, selector):
+ """ Wait until element matching CSS selector is visible on the page """
+ is_visible = lambda driver: self.find(selector).is_displayed()
+ msg = 'An element matching "%s" should be visible' % selector
+ Wait(self.driver).until(is_visible, msg)
+ return self.find(selector)
+
+ def wait_until_focused(self, selector):
+ """ Wait until element matching CSS selector has focus """
+ is_focused = \
+ lambda driver: self.find(selector) == self.focused_element()
+ msg = 'An element matching "%s" should be focused' % selector
+ Wait(self.driver).until(is_focused, msg)
+ return self.find(selector)
+
+ def enter_text(self, selector, value):
+ """ Insert text into element matching selector """
+ # note that keyup events don't occur until the element is clicked
+ # (in the case of <input type="text"...>, for example), so simulate
+ # user clicking the element before inserting text into it
+ field = self.click(selector)
+
+ field.send_keys(value)
+ return field
+
+ def click(self, selector):
+ """ Click on element which matches CSS selector """
+ element = self.wait_until_visible(selector)
+ element.click()
+ return element
+
+ def get_page_source(self):
+ """ Get raw HTML for the current page """
+ return self.driver.page_source
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py
index e4223f482..b86f29bdd 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py
@@ -27,6 +27,7 @@ from tests.browser.selenium_helpers import SeleniumTestCase
from orm.models import BitbakeVersion, Release, Project, Build, Target
+
class TestAllBuildsPage(SeleniumTestCase):
""" Tests for all builds page /builds/ """
@@ -57,6 +58,13 @@ class TestAllBuildsPage(SeleniumTestCase):
'outcome': Build.SUCCEEDED
}
+ self.project1_build_failure = {
+ 'project': self.project1,
+ 'started_on': now,
+ 'completed_on': now,
+ 'outcome': Build.FAILED
+ }
+
self.default_project_build_success = {
'project': self.default_project,
'started_on': now,
@@ -64,6 +72,46 @@ class TestAllBuildsPage(SeleniumTestCase):
'outcome': Build.SUCCEEDED
}
+ def _get_build_time_element(self, build):
+ """
+ Return the HTML element containing the build time for a build
+ in the recent builds area
+ """
+ selector = 'div[data-latest-build-result="%s"] ' \
+ '[data-role="data-recent-build-buildtime-field"]' % build.id
+
+ # because this loads via Ajax, wait for it to be visible
+ self.wait_until_present(selector)
+
+ build_time_spans = self.find_all(selector)
+
+ self.assertEqual(len(build_time_spans), 1)
+
+ return build_time_spans[0]
+
+ def _get_row_for_build(self, build):
+ """ Get the table row for the build from the all builds table """
+ self.wait_until_present('#allbuildstable')
+
+ rows = self.find_all('#allbuildstable tr')
+
+ # look for the row with a download link on the recipe which matches the
+ # build ID
+ url = reverse('builddashboard', args=(build.id,))
+ selector = 'td.target a[href="%s"]' % url
+
+ found_row = None
+ for row in rows:
+
+ outcome_links = row.find_elements_by_css_selector(selector)
+ if len(outcome_links) == 1:
+ found_row = row
+ break
+
+ self.assertNotEqual(found_row, None)
+
+ return found_row
+
def test_show_tasks_with_suffix(self):
""" Task should be shown as suffix on build name """
build = Build.objects.create(**self.project1_build_success)
@@ -95,17 +143,17 @@ class TestAllBuildsPage(SeleniumTestCase):
url = reverse('all-builds')
self.get(url)
- # shouldn't see a run again button for command-line builds
- selector = 'div[data-latest-build-result="%s"] button' % default_build.id
+ # shouldn't see a rebuild button for command-line builds
+ selector = 'div[data-latest-build-result="%s"] .rebuild-btn' % default_build.id
run_again_button = self.find_all(selector)
self.assertEqual(len(run_again_button), 0,
- 'should not see a run again button for cli builds')
+ 'should not see a rebuild button for cli builds')
- # should see a run again button for non-command-line builds
- selector = 'div[data-latest-build-result="%s"] button' % build1.id
+ # should see a rebuild button for non-command-line builds
+ selector = 'div[data-latest-build-result="%s"] .rebuild-btn' % build1.id
run_again_button = self.find_all(selector)
self.assertEqual(len(run_again_button), 1,
- 'should see a run again button for non-cli builds')
+ 'should see a rebuild button for non-cli builds')
def test_tooltips_on_project_name(self):
"""
@@ -124,7 +172,7 @@ class TestAllBuildsPage(SeleniumTestCase):
# get the project name cells from the table
cells = self.find_all('#allbuildstable td[class="project"]')
- selector = 'i.get-help'
+ selector = 'span.get-help'
for cell in cells:
content = cell.get_attribute('innerHTML')
@@ -141,3 +189,45 @@ class TestAllBuildsPage(SeleniumTestCase):
else:
msg = 'found unexpected project name cell in all builds table'
self.fail(msg)
+
+ def test_builds_time_links(self):
+ """
+ Successful builds should have links on the time column and in the
+ recent builds area; failed builds should not have links on the time column,
+ or in the recent builds area
+ """
+ build1 = Build.objects.create(**self.project1_build_success)
+ build2 = Build.objects.create(**self.project1_build_failure)
+
+ # add some targets to these builds so they have recipe links
+ # (and so we can find the row in the ToasterTable corresponding to
+ # a particular build)
+ Target.objects.create(build=build1, target='foo')
+ Target.objects.create(build=build2, target='bar')
+
+ url = reverse('all-builds')
+ self.get(url)
+
+ # test recent builds area for successful build
+ element = self._get_build_time_element(build1)
+ links = element.find_elements_by_css_selector('a')
+ msg = 'should be a link on the build time for a successful recent build'
+ self.assertEquals(len(links), 1, msg)
+
+ # test recent builds area for failed build
+ element = self._get_build_time_element(build2)
+ links = element.find_elements_by_css_selector('a')
+ msg = 'should not be a link on the build time for a failed recent build'
+ self.assertEquals(len(links), 0, msg)
+
+ # test the time column for successful build
+ build1_row = self._get_row_for_build(build1)
+ links = build1_row.find_elements_by_css_selector('td.time a')
+ msg = 'should be a link on the build time for a successful build'
+ self.assertEquals(len(links), 1, msg)
+
+ # test the time column for failed build
+ build2_row = self._get_row_for_build(build2)
+ links = build2_row.find_elements_by_css_selector('td.time a')
+ msg = 'should not be a link on the build time for a failed build'
+ self.assertEquals(len(links), 0, msg)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py
index ed8e620db..44da64075 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py
@@ -93,7 +93,7 @@ class TestAllProjectsPage(SeleniumTestCase):
"""
url = reverse('all-projects')
self.get(url)
- self.wait_until_visible('#no-results-projectstable')
+ self.wait_until_visible('#empty-state-projectstable')
rows = self.find_all('#projectstable tbody tr')
self.assertEqual(len(rows), 0, 'should be no projects displayed')
@@ -122,12 +122,13 @@ class TestAllProjectsPage(SeleniumTestCase):
self._add_non_default_project()
self.get(reverse('all-projects'))
+ self.wait_until_visible("#projectstable tr")
# find the row for the default project
default_project_row = self._get_row_for_project(self.default_project.name)
# check the release text for the default project
- selector = 'span[data-project-field="release"] span.muted'
+ selector = 'span[data-project-field="release"] span.text-muted'
element = default_project_row.find_element_by_css_selector(selector)
text = element.text.strip()
self.assertEqual(text, 'Not applicable',
@@ -137,7 +138,7 @@ class TestAllProjectsPage(SeleniumTestCase):
other_project_row = self._get_row_for_project(self.project.name)
# check the link in the release cell for the other project
- selector = 'span[data-project-field="release"] a'
+ selector = 'span[data-project-field="release"]'
element = other_project_row.find_element_by_css_selector(selector)
text = element.text.strip()
self.assertEqual(text, self.release.name,
@@ -156,11 +157,13 @@ class TestAllProjectsPage(SeleniumTestCase):
self.get(reverse('all-projects'))
+ self.wait_until_visible("#projectstable tr")
+
# find the row for the default project
default_project_row = self._get_row_for_project(self.default_project.name)
# check the machine cell for the default project
- selector = 'span[data-project-field="machine"] span.muted'
+ selector = 'span[data-project-field="machine"] span.text-muted'
element = default_project_row.find_element_by_css_selector(selector)
text = element.text.strip()
self.assertEqual(text, 'Not applicable',
@@ -170,7 +173,7 @@ class TestAllProjectsPage(SeleniumTestCase):
other_project_row = self._get_row_for_project(self.project.name)
# check the link in the machine cell for the other project
- selector = 'span[data-project-field="machine"] a'
+ selector = 'span[data-project-field="machine"]'
element = other_project_row.find_element_by_css_selector(selector)
text = element.text.strip()
self.assertEqual(text, self.MACHINE_NAME,
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py
index 5e0874947..f8ccb5452 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py
@@ -22,10 +22,10 @@
from django.core.urlresolvers import reverse
from django.utils import timezone
-from selenium_helpers import SeleniumTestCase
+from tests.browser.selenium_helpers import SeleniumTestCase
from orm.models import Project, Release, BitbakeVersion, Build, LogMessage
-from orm.models import Layer, Layer_Version, Recipe, CustomImageRecipe
+from orm.models import Layer, Layer_Version, Recipe, CustomImageRecipe, Variable
class TestBuildDashboardPage(SeleniumTestCase):
""" Tests for the build dashboard /build/X """
@@ -42,11 +42,27 @@ class TestBuildDashboardPage(SeleniumTestCase):
self.build1 = Build.objects.create(project=project,
started_on=now,
- completed_on=now)
+ completed_on=now,
+ outcome=Build.SUCCEEDED)
self.build2 = Build.objects.create(project=project,
started_on=now,
- completed_on=now)
+ completed_on=now,
+ outcome=Build.SUCCEEDED)
+
+ self.build3 = Build.objects.create(project=project,
+ started_on=now,
+ completed_on=now,
+ outcome=Build.FAILED)
+
+ # add Variable objects to the successful builds, as this is the criterion
+ # used to determine whether the left-hand panel should be displayed
+ Variable.objects.create(build=self.build1,
+ variable_name='Foo',
+ variable_value='Bar')
+ Variable.objects.create(build=self.build2,
+ variable_name='Foo',
+ variable_value='Bar')
# exception
msg1 = 'an exception was thrown'
@@ -64,6 +80,22 @@ class TestBuildDashboardPage(SeleniumTestCase):
message=msg2
)
+ # error on the failed build
+ msg3 = 'an error occurred'
+ self.error_message = LogMessage.objects.create(
+ build=self.build3,
+ level=LogMessage.ERROR,
+ message=msg3
+ )
+
+ # warning on the failed build
+ msg4 = 'DANGER WILL ROBINSON'
+ self.warning_message = LogMessage.objects.create(
+ build=self.build3,
+ level=LogMessage.WARNING,
+ message=msg4
+ )
+
# recipes related to the build, for testing the edit custom image/new
# custom image buttons
layer = Layer.objects.create(name='alayer')
@@ -71,6 +103,11 @@ class TestBuildDashboardPage(SeleniumTestCase):
layer=layer, build=self.build1
)
+ # non-image recipes related to a build, for testing the new custom
+ # image button
+ layer_version2 = Layer_Version.objects.create(layer=layer,
+ build=self.build3)
+
# image recipes
self.image_recipe1 = Recipe.objects.create(
name='recipeA',
@@ -140,38 +177,47 @@ class TestBuildDashboardPage(SeleniumTestCase):
dashboard for the Build object build
"""
self._get_build_dashboard(build)
- return self.find_all('#errors div.alert-error')
+ return self.find_all('#errors div.alert-danger')
- def _check_for_log_message(self, build, log_message):
- """
- Check whether the LogMessage instance <log_message> is
- represented as an HTML error in the dashboard page for the Build object
- build
+ def _check_for_log_message(self, message_elements, log_message):
"""
- errors = self._get_build_dashboard_errors(build)
- self.assertEqual(len(errors), 2)
+ Check that the LogMessage <log_message> has a representation in
+ the HTML elements <message_elements>.
+
+ message_elements: WebElements representing the log messages shown
+ in the build dashboard; each should have a <pre> element inside
+ it with a data-log-message-id attribute
+ log_message: orm.models.LogMessage instance
+ """
expected_text = log_message.message
- expected_id = str(log_message.id)
+ expected_pk = str(log_message.pk)
found = False
- for error in errors:
- error_text = error.find_element_by_tag_name('pre').text
- text_matches = (error_text == expected_text)
+ for element in message_elements:
+ log_message_text = element.find_element_by_tag_name('pre').text.strip()
+ text_matches = (log_message_text == expected_text)
- error_id = error.get_attribute('data-error')
- id_matches = (error_id == expected_id)
+ log_message_pk = element.get_attribute('data-log-message-id')
+ id_matches = (log_message_pk == expected_pk)
if text_matches and id_matches:
found = True
break
- template_vars = (expected_text, error_text,
- expected_id, error_id)
- assertion_error_msg = 'exception not found as error: ' \
- 'expected text "%s" and got "%s"; ' \
- 'expected ID %s and got %s' % template_vars
- self.assertTrue(found, assertion_error_msg)
+ template_vars = (expected_text, expected_pk)
+ assertion_failed_msg = 'message not found: ' \
+ 'expected text "%s" and ID %s' % template_vars
+ self.assertTrue(found, assertion_failed_msg)
+
+ def _check_for_error_message(self, build, log_message):
+ """
+ Check whether the LogMessage instance <log_message> is
+ represented as an HTML error in the dashboard page for the Build object
+ build
+ """
+ errors = self._get_build_dashboard_errors(build)
+ self._check_for_log_message(errors, log_message)
def _check_labels_in_modal(self, modal, expected):
"""
@@ -179,37 +225,29 @@ class TestBuildDashboardPage(SeleniumTestCase):
the WebElement modal match the list of text values in expected
"""
# labels containing the radio buttons we're testing for
- labels = modal.find_elements_by_tag_name('label')
-
- # because the label content has the structure
- # label text
- # <input...>
- # we have to regex on its innerHTML, as we can't just retrieve the
- # "label text" on its own via the Selenium API
- labels_text = sorted(map(
- lambda label: label.get_attribute('innerHTML'), labels
- ))
-
- expected = sorted(expected)
+ labels = modal.find_elements_by_css_selector(".radio")
+ labels_text = [lab.text for lab in labels]
self.assertEqual(len(labels_text), len(expected))
- for idx, label_text in enumerate(labels_text):
- self.assertRegexpMatches(label_text, expected[idx])
+ for expected_text in expected:
+ self.assertTrue(expected_text in labels_text,
+ "Could not find %s in %s" % (expected_text,
+ labels_text))
def test_exceptions_show_as_errors(self):
"""
LogMessages with level EXCEPTION should display in the errors
section of the page
"""
- self._check_for_log_message(self.build1, self.exception_message)
+ self._check_for_error_message(self.build1, self.exception_message)
def test_criticals_show_as_errors(self):
"""
LogMessages with level CRITICAL should display in the errors
section of the page
"""
- self._check_for_log_message(self.build1, self.critical_message)
+ self._check_for_error_message(self.build1, self.critical_message)
def test_edit_custom_image_button(self):
"""
@@ -217,7 +255,13 @@ class TestBuildDashboardPage(SeleniumTestCase):
the user choose one of them to edit
"""
self._get_build_dashboard(self.build1)
+
+ # click the "edit custom image" button, which populates the modal
+ selector = '[data-role="edit-custom-image-trigger"]'
+ self.click(selector)
+
modal = self.driver.find_element_by_id('edit-custom-image-modal')
+ self.wait_until_visible("#edit-custom-image-modal")
# recipes we expect to see in the edit custom image modal
expected_recipes = [
@@ -235,10 +279,11 @@ class TestBuildDashboardPage(SeleniumTestCase):
self._get_build_dashboard(self.build1)
# click the "new custom image" button, which populates the modal
- selector = '[data-role="new-custom-image-trigger"] button'
+ selector = '[data-role="new-custom-image-trigger"]'
self.click(selector)
modal = self.driver.find_element_by_id('new-custom-image-modal')
+ self.wait_until_visible("#new-custom-image-modal")
# recipes we expect to see in the new custom image modal
expected_recipes = [
@@ -249,3 +294,54 @@ class TestBuildDashboardPage(SeleniumTestCase):
]
self._check_labels_in_modal(modal, expected_recipes)
+
+ def test_new_custom_image_button_no_image(self):
+ """
+ Check that a build which builds non-image recipes doesn't show
+ the new custom image button on the dashboard.
+ """
+ self._get_build_dashboard(self.build3)
+ selector = '[data-role="new-custom-image-trigger"]'
+ self.assertFalse(self.element_exists(selector),
+ 'new custom image button should not show for builds which ' \
+ 'don\'t have any image recipes')
+
+ def test_left_panel(self):
+ """"
+ Builds which succeed should have a left panel and a build summary
+ """
+ self._get_build_dashboard(self.build1)
+
+ left_panel = self.find_all('#nav')
+ self.assertEqual(len(left_panel), 1)
+
+ build_summary = self.find_all('[data-role="build-summary-heading"]')
+ self.assertEqual(len(build_summary), 1)
+
+ def test_failed_no_left_panel(self):
+ """
+ Builds which fail should have no left panel and no build summary
+ """
+ self._get_build_dashboard(self.build3)
+
+ left_panel = self.find_all('#nav')
+ self.assertEqual(len(left_panel), 0)
+
+ build_summary = self.find_all('[data-role="build-summary-heading"]')
+ self.assertEqual(len(build_summary), 0)
+
+ def test_failed_shows_errors_and_warnings(self):
+ """
+ Failed builds should still show error and warning messages
+ """
+ self._get_build_dashboard(self.build3)
+
+ errors = self.find_all('#errors div.alert-danger')
+ self._check_for_log_message(errors, self.error_message)
+
+ # expand the warnings area
+ self.click('#warning-toggle')
+ self.wait_until_visible('#warnings div.alert-warning')
+
+ warnings = self.find_all('#warnings div.alert-warning')
+ self._check_for_log_message(warnings, self.warning_message)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py
new file mode 100644
index 000000000..1c627ad49
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_artifacts.py
@@ -0,0 +1,222 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from django.core.urlresolvers import reverse
+from django.utils import timezone
+
+from tests.browser.selenium_helpers import SeleniumTestCase
+
+from orm.models import Project, Release, BitbakeVersion, Build, Target, Package
+from orm.models import Target_Image_File, TargetSDKFile, TargetKernelFile
+from orm.models import Target_Installed_Package, Variable
+
+class TestBuildDashboardPageArtifacts(SeleniumTestCase):
+ """ Tests for artifacts on the build dashboard /build/X """
+
+ def setUp(self):
+ bbv = BitbakeVersion.objects.create(name='bbv1', giturl='/tmp/',
+ branch='master', dirpath="")
+ release = Release.objects.create(name='release1',
+ bitbake_version=bbv)
+ self.project = Project.objects.create_project(name='test project',
+ release=release)
+
+ def _get_build_dashboard(self, build):
+ """
+ Navigate to the build dashboard for build
+ """
+ url = reverse('builddashboard', args=(build.id,))
+ self.get(url)
+
+ def _has_build_artifacts_heading(self):
+ """
+ Check whether the "Build artifacts" heading is visible (True if it
+ is, False otherwise).
+ """
+ return self.element_exists('[data-heading="build-artifacts"]')
+
+ def _has_images_menu_option(self):
+ """
+ Try to get the "Images" list element from the left-hand menu in the
+ build dashboard, and return True if it is present, False otherwise.
+ """
+ return self.element_exists('li.nav-header[data-menu-heading="images"]')
+
+ def test_no_artifacts(self):
+ """
+ If a build produced no artifacts, the artifacts heading and images
+ menu option shouldn't show.
+ """
+ now = timezone.now()
+ build = Build.objects.create(project=self.project,
+ started_on=now, completed_on=now, outcome=Build.SUCCEEDED)
+
+ Target.objects.create(is_image=False, build=build, task='',
+ target='mpfr-native')
+
+ self._get_build_dashboard(build)
+
+ # check build artifacts heading
+ msg = 'Build artifacts heading should not be displayed for non-image' \
+ 'builds'
+ self.assertFalse(self._has_build_artifacts_heading(), msg)
+
+ # check "Images" option in left-hand menu (should not be there)
+ msg = 'Images option should not be shown in left-hand menu'
+ self.assertFalse(self._has_images_menu_option(), msg)
+
+ def test_sdk_artifacts(self):
+ """
+ If a build produced SDK artifacts, they should be shown, but the section
+ for image files and the images menu option should be hidden.
+
+ The packages count and size should also be hidden.
+ """
+ now = timezone.now()
+ build = Build.objects.create(project=self.project,
+ started_on=now, completed_on=timezone.now(),
+ outcome=Build.SUCCEEDED)
+
+ target = Target.objects.create(is_image=True, build=build,
+ task='populate_sdk', target='core-image-minimal')
+
+ sdk_file1 = TargetSDKFile.objects.create(target=target,
+ file_size=100000,
+ file_name='/home/foo/core-image-minimal.toolchain.sh')
+
+ sdk_file2 = TargetSDKFile.objects.create(target=target,
+ file_size=120000,
+ file_name='/home/foo/x86_64.toolchain.sh')
+
+ self._get_build_dashboard(build)
+
+ # check build artifacts heading
+ msg = 'Build artifacts heading should be displayed for SDK ' \
+ 'builds which generate artifacts'
+ self.assertTrue(self._has_build_artifacts_heading(), msg)
+
+ # check "Images" option in left-hand menu (should not be there)
+ msg = 'Images option should not be shown in left-hand menu for ' \
+ 'builds which didn\'t generate an image file'
+ self.assertFalse(self._has_images_menu_option(), msg)
+
+ # check links to SDK artifacts
+ sdk_artifact_links = self.find_all('[data-links="sdk-artifacts"] li')
+ self.assertEqual(len(sdk_artifact_links), 2,
+ 'should be links to 2 SDK artifacts')
+
+ # package count and size should not be visible, no link on
+ # target name
+ selector = '[data-value="target-package-count"]'
+ self.assertFalse(self.element_exists(selector),
+ 'package count should not be shown for non-image builds')
+
+ selector = '[data-value="target-package-size"]'
+ self.assertFalse(self.element_exists(selector),
+ 'package size should not be shown for non-image builds')
+
+ selector = '[data-link="target-packages"]'
+ self.assertFalse(self.element_exists(selector),
+ 'link to target packages should not be on target heading')
+
+ def test_image_artifacts(self):
+ """
+ If a build produced image files, kernel artifacts, and manifests,
+ they should all be shown, as well as the image link in the left-hand
+ menu.
+
+ The packages count and size should be shown, with a link to the
+ package display page.
+ """
+ now = timezone.now()
+ build = Build.objects.create(project=self.project,
+ started_on=now, completed_on=timezone.now(),
+ outcome=Build.SUCCEEDED)
+
+ # add a variable to the build so that it counts as "started"
+ Variable.objects.create(build=build,
+ variable_name='Christopher',
+ variable_value='Lee')
+
+ target = Target.objects.create(is_image=True, build=build,
+ task='', target='core-image-minimal',
+ license_manifest_path='/home/foo/license.manifest',
+ package_manifest_path='/home/foo/package.manifest')
+
+ image_file = Target_Image_File.objects.create(target=target,
+ file_name='/home/foo/core-image-minimal.ext4', file_size=9000)
+
+ kernel_file1 = TargetKernelFile.objects.create(target=target,
+ file_name='/home/foo/bzImage', file_size=2000)
+
+ kernel_file2 = TargetKernelFile.objects.create(target=target,
+ file_name='/home/foo/bzImage', file_size=2000)
+
+ package = Package.objects.create(build=build, name='foo', size=1024,
+ installed_name='foo1')
+ installed_package = Target_Installed_Package.objects.create(
+ target=target, package=package)
+
+ self._get_build_dashboard(build)
+
+ # check build artifacts heading
+ msg = 'Build artifacts heading should be displayed for image ' \
+ 'builds'
+ self.assertTrue(self._has_build_artifacts_heading(), msg)
+
+ # check "Images" option in left-hand menu (should be there)
+ msg = 'Images option should be shown in left-hand menu for image builds'
+ self.assertTrue(self._has_images_menu_option(), msg)
+
+ # check link to image file
+ selector = '[data-links="image-artifacts"] li'
+ self.assertTrue(self.element_exists(selector),
+ 'should be a link to the image file (selector %s)' % selector)
+
+ # check links to kernel artifacts
+ kernel_artifact_links = \
+ self.find_all('[data-links="kernel-artifacts"] li')
+ self.assertEqual(len(kernel_artifact_links), 2,
+ 'should be links to 2 kernel artifacts')
+
+ # check manifest links
+ selector = 'a[data-link="license-manifest"]'
+ self.assertTrue(self.element_exists(selector),
+ 'should be a link to the license manifest (selector %s)' % selector)
+
+ selector = 'a[data-link="package-manifest"]'
+ self.assertTrue(self.element_exists(selector),
+ 'should be a link to the package manifest (selector %s)' % selector)
+
+ # check package count and size, link on target name
+ selector = '[data-value="target-package-count"]'
+ element = self.find(selector)
+ self.assertEquals(element.text, '1',
+ 'package count should be shown for image builds')
+
+ selector = '[data-value="target-package-size"]'
+ element = self.find(selector)
+ self.assertEquals(element.text, '1.0 KB',
+ 'package size should be shown for image builds')
+
+ selector = '[data-link="target-packages"]'
+ self.assertTrue(self.element_exists(selector),
+ 'link to target packages should be on target heading')
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_recipes.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_recipes.py
new file mode 100644
index 000000000..ed18324e5
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_recipes.py
@@ -0,0 +1,66 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from django.core.urlresolvers import reverse
+from django.utils import timezone
+from tests.browser.selenium_helpers import SeleniumTestCase
+from orm.models import Project, Build, Recipe, Task, Layer, Layer_Version
+from orm.models import Target
+
+class TestBuilddashboardPageRecipes(SeleniumTestCase):
+ """ Test build dashboard recipes sub-page """
+
+ def setUp(self):
+ project = Project.objects.get_or_create_default_project()
+
+ now = timezone.now()
+
+ self.build = Build.objects.create(project=project,
+ started_on=now,
+ completed_on=now)
+
+ layer = Layer.objects.create()
+
+ layer_version = Layer_Version.objects.create(layer=layer,
+ build=self.build)
+
+ recipe = Recipe.objects.create(layer_version=layer_version)
+
+ task = Task.objects.create(build=self.build, recipe=recipe, order=1)
+
+ Target.objects.create(build=self.build, task=task, target='do_build')
+
+ def test_build_recipes_columns(self):
+ """
+ Check that non-hideable columns of the table on the recipes sub-page
+ are disabled on the edit columns dropdown.
+ """
+ url = reverse('recipes', args=(self.build.id,))
+ self.get(url)
+
+ self.wait_until_visible('#edit-columns-button')
+
+ # check that options for the non-hideable columns are disabled
+ non_hideable = ['name', 'version']
+
+ for column in non_hideable:
+ selector = 'input#checkbox-%s[disabled="disabled"]' % column
+ self.wait_until_present(selector)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_tasks.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_tasks.py
new file mode 100644
index 000000000..da50f1601
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page_tasks.py
@@ -0,0 +1,65 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from django.core.urlresolvers import reverse
+from django.utils import timezone
+from tests.browser.selenium_helpers import SeleniumTestCase
+from orm.models import Project, Build, Recipe, Task, Layer, Layer_Version
+from orm.models import Target
+
+class TestBuilddashboardPageTasks(SeleniumTestCase):
+ """ Test build dashboard tasks sub-page """
+
+ def setUp(self):
+ project = Project.objects.get_or_create_default_project()
+
+ now = timezone.now()
+
+ self.build = Build.objects.create(project=project,
+ started_on=now,
+ completed_on=now)
+
+ layer = Layer.objects.create()
+
+ layer_version = Layer_Version.objects.create(layer=layer)
+
+ recipe = Recipe.objects.create(layer_version=layer_version)
+
+ task = Task.objects.create(build=self.build, recipe=recipe, order=1)
+
+ Target.objects.create(build=self.build, task=task, target='do_build')
+
+ def test_build_tasks_columns(self):
+ """
+ Check that non-hideable columns of the table on the tasks sub-page
+ are disabled on the edit columns dropdown.
+ """
+ url = reverse('tasks', args=(self.build.id,))
+ self.get(url)
+
+ self.wait_until_visible('#edit-columns-button')
+
+ # check that options for the non-hideable columns are disabled
+ non_hideable = ['order', 'task_name', 'recipe__name']
+
+ for column in non_hideable:
+ selector = 'input#checkbox-%s[disabled="disabled"]' % column
+ self.wait_until_present(selector)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_js_unit_tests.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_js_unit_tests.py
index e63da8e7a..3c0b96252 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_js_unit_tests.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_js_unit_tests.py
@@ -38,11 +38,11 @@ class TestJsUnitTests(SeleniumTestCase):
def test_that_js_unit_tests_pass(self):
url = reverse('js-unit-tests')
self.get(url)
- self.wait_until_present('#tests-failed')
+ self.wait_until_present('#qunit-testresult .failed')
- failed = self.find("#tests-failed").text
- passed = self.find("#tests-passed").text
- total = self.find("#tests-total").text
+ failed = self.find("#qunit-testresult .failed").text
+ passed = self.find("#qunit-testresult .passed").text
+ total = self.find("#qunit-testresult .total").text
logger.info("Js unit tests completed %s out of %s passed, %s failed",
passed,
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py
new file mode 100644
index 000000000..6392d1efb
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py
@@ -0,0 +1,215 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from django.core.urlresolvers import reverse
+from tests.browser.selenium_helpers import SeleniumTestCase
+
+from orm.models import Layer, Layer_Version, Project, LayerSource, Release
+from orm.models import BitbakeVersion
+
+from selenium.webdriver.support import expected_conditions as EC
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.common.by import By
+
+
+class TestLayerDetailsPage(SeleniumTestCase):
+ """ Test layerdetails page works correctly """
+
+ def __init__(self, *args, **kwargs):
+ super(TestLayerDetailsPage, self).__init__(*args, **kwargs)
+
+ self.initial_values = None
+ self.url = None
+ self.imported_layer_version = None
+
+ def setUp(self):
+ release = Release.objects.create(
+ name='baz',
+ bitbake_version=BitbakeVersion.objects.create(name='v1')
+ )
+
+ # project to add new custom images to
+ self.project = Project.objects.create(name='foo', release=release)
+
+ name = "meta-imported"
+ vcs_url = "git://example.com/meta-imported"
+ subdir = "/layer"
+ gitrev = "d33d"
+ summary = "A imported layer"
+ description = "This was imported"
+
+ imported_layer = Layer.objects.create(name=name,
+ vcs_url=vcs_url,
+ summary=summary,
+ description=description)
+
+ self.imported_layer_version = Layer_Version.objects.create(
+ layer=imported_layer,
+ layer_source=LayerSource.TYPE_IMPORTED,
+ branch=gitrev,
+ commit=gitrev,
+ dirpath=subdir,
+ project=self.project)
+
+ self.initial_values = [name, vcs_url, subdir, gitrev, summary,
+ description]
+ self.url = reverse('layerdetails',
+ args=(self.project.pk,
+ self.imported_layer_version.pk))
+
+ def test_edit_layerdetails(self):
+ """ Edit all the editable fields for the layer refresh the page and
+ check that the new values exist"""
+
+ self.get(self.url)
+
+ self.click("#add-remove-layer-btn")
+ self.click("#edit-layer-source")
+ self.click("#repo")
+
+ self.wait_until_visible("#layer-git-repo-url")
+
+ # Open every edit box
+ for btn in self.find_all("dd .glyphicon-edit"):
+ btn.click()
+
+ # Wait for the inputs to become visible
+ self.wait_until_visible("#layer-git input[type=text]")
+ self.wait_until_visible("dd textarea")
+
+ # Edit each value
+ for inputs in self.find_all("#layer-git input[type=text]") + \
+ self.find_all("dd textarea"):
+ # ignore the tt inputs (twitter typeahead input)
+ if "tt-" in inputs.get_attribute("class"):
+ continue
+
+ value = inputs.get_attribute("value")
+
+ self.assertTrue(value in self.initial_values,
+ "Expecting any of \"%s\"but got \"%s\"" %
+ (self.initial_values, value))
+
+ inputs.send_keys("-edited")
+
+ # Save the new values
+ for save_btn in self.find_all(".change-btn"):
+ save_btn.click()
+
+ self.click("#save-changes-for-switch")
+ self.wait_until_visible("#edit-layer-source")
+
+ # Refresh the page to see if the new values are returned
+ self.get(self.url)
+
+ new_values = ["%s-edited" % old_val
+ for old_val in self.initial_values]
+
+ for inputs in self.find_all('#layer-git input[type="text"]') + \
+ self.find_all('dd textarea'):
+ # ignore the tt inputs (twitter typeahead input)
+ if "tt-" in inputs.get_attribute("class"):
+ continue
+
+ value = inputs.get_attribute("value")
+
+ self.assertTrue(value in new_values,
+ "Expecting any of \"%s\" but got \"%s\"" %
+ (new_values, value))
+
+ # Now convert it to a local layer
+ self.click("#edit-layer-source")
+ self.click("#dir")
+ dir_input = self.wait_until_visible("#layer-dir-path-in-details")
+
+ new_dir = "/home/test/my-meta-dir"
+ dir_input.send_keys(new_dir)
+
+ self.click("#save-changes-for-switch")
+ self.wait_until_visible("#edit-layer-source")
+
+ # Refresh the page to see if the new values are returned
+ self.get(self.url)
+ dir_input = self.find("#layer-dir-path-in-details")
+ self.assertTrue(new_dir in dir_input.get_attribute("value"),
+ "Expected %s in the dir value for layer directory" %
+ new_dir)
+
+ def test_delete_layer(self):
+ """ Delete the layer """
+
+ self.get(self.url)
+
+ # Wait for the tables to load to avoid a race condition where the
+ # toaster tables have made an async request. If the layer is deleted
+ # before the request finishes it will cause an exception and fail this
+ # test.
+ wait = WebDriverWait(self.driver, 30)
+
+ wait.until(EC.text_to_be_present_in_element(
+ (By.CLASS_NAME,
+ "table-count-recipestable"), "0"))
+
+ wait.until(EC.text_to_be_present_in_element(
+ (By.CLASS_NAME,
+ "table-count-machinestable"), "0"))
+
+ self.click('a[data-target="#delete-layer-modal"]')
+ self.wait_until_visible("#delete-layer-modal")
+ self.click("#layer-delete-confirmed")
+
+ notification = self.wait_until_visible("#change-notification-msg")
+ expected_text = "You have deleted 1 layer from your project: %s" % \
+ self.imported_layer_version.layer.name
+
+ self.assertTrue(expected_text in notification.text,
+ "Expected notification text \"%s\" not found instead"
+ "it was \"%s\"" %
+ (expected_text, notification.text))
+
+ def test_addrm_to_project(self):
+ self.get(self.url)
+
+ # Add the layer
+ self.click("#add-remove-layer-btn")
+
+ notification = self.wait_until_visible("#change-notification-msg")
+
+ expected_text = "You have added 1 layer to your project: %s" % \
+ self.imported_layer_version.layer.name
+
+ self.assertTrue(expected_text in notification.text,
+ "Expected notification text %s not found was "
+ " \"%s\" instead" %
+ (expected_text, notification.text))
+
+ # Remove the layer
+ self.click("#add-remove-layer-btn")
+
+ notification = self.wait_until_visible("#change-notification-msg")
+
+ expected_text = "You have removed 1 layer from your project: %s" % \
+ self.imported_layer_version.layer.name
+
+ self.assertTrue(expected_text in notification.text,
+ "Expected notification text %s not found was "
+ " \"%s\" instead" %
+ (expected_text, notification.text))
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_most_recent_builds_states.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_most_recent_builds_states.py
new file mode 100644
index 000000000..abc0b0bc8
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_most_recent_builds_states.py
@@ -0,0 +1,211 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from django.core.urlresolvers import reverse
+from django.utils import timezone
+from tests.browser.selenium_helpers import SeleniumTestCase
+from tests.browser.selenium_helpers_base import Wait
+from orm.models import Project, Build, Task, Recipe, Layer, Layer_Version
+from bldcontrol.models import BuildRequest
+
+class TestMostRecentBuildsStates(SeleniumTestCase):
+ """ Test states update correctly in most recent builds area """
+
+ def _create_build_request(self):
+ project = Project.objects.get_or_create_default_project()
+
+ now = timezone.now()
+
+ build = Build.objects.create(project=project, build_name='fakebuild',
+ started_on=now, completed_on=now)
+
+ return BuildRequest.objects.create(build=build, project=project,
+ state=BuildRequest.REQ_QUEUED)
+
+ def _create_recipe(self):
+ """ Add a recipe to the database and return it """
+ layer = Layer.objects.create()
+ layer_version = Layer_Version.objects.create(layer=layer)
+ return Recipe.objects.create(name='foo', layer_version=layer_version)
+
+ def _check_build_states(self, build_request):
+ recipes_to_parse = 10
+ url = reverse('all-builds')
+ self.get(url)
+
+ build = build_request.build
+ base_selector = '[data-latest-build-result="%s"] ' % build.id
+
+ # build queued; check shown as queued
+ selector = base_selector + '[data-build-state="Queued"]'
+ element = self.wait_until_visible(selector)
+ self.assertRegexpMatches(element.get_attribute('innerHTML'),
+ 'Build queued', 'build should show queued status')
+
+ # waiting for recipes to be parsed
+ build.outcome = Build.IN_PROGRESS
+ build.recipes_to_parse = recipes_to_parse
+ build.recipes_parsed = 0
+
+ build_request.state = BuildRequest.REQ_INPROGRESS
+ build_request.save()
+
+ self.get(url)
+
+ selector = base_selector + '[data-build-state="Parsing"]'
+ element = self.wait_until_visible(selector)
+
+ bar_selector = '#recipes-parsed-percentage-bar-%s' % build.id
+ bar_element = element.find_element_by_css_selector(bar_selector)
+ self.assertEqual(bar_element.value_of_css_property('width'), '0px',
+ 'recipe parse progress should be at 0')
+
+ # recipes being parsed; check parse progress
+ build.recipes_parsed = 5
+ build.save()
+
+ self.get(url)
+
+ element = self.wait_until_visible(selector)
+ bar_element = element.find_element_by_css_selector(bar_selector)
+ recipe_bar_updated = lambda driver: \
+ bar_element.get_attribute('style') == 'width: 50%;'
+ msg = 'recipe parse progress bar should update to 50%'
+ element = Wait(self.driver).until(recipe_bar_updated, msg)
+
+ # all recipes parsed, task started, waiting for first task to finish;
+ # check status is shown as "Tasks starting..."
+ build.recipes_parsed = recipes_to_parse
+ build.save()
+
+ recipe = self._create_recipe()
+ task1 = Task.objects.create(build=build, recipe=recipe,
+ task_name='Lionel')
+ task2 = Task.objects.create(build=build, recipe=recipe,
+ task_name='Jeffries')
+
+ self.get(url)
+
+ selector = base_selector + '[data-build-state="Starting"]'
+ element = self.wait_until_visible(selector)
+ self.assertRegexpMatches(element.get_attribute('innerHTML'),
+ 'Tasks starting', 'build should show "tasks starting" status')
+
+ # first task finished; check tasks progress bar
+ task1.order = 1
+ task1.save()
+
+ self.get(url)
+
+ selector = base_selector + '[data-build-state="In Progress"]'
+ element = self.wait_until_visible(selector)
+
+ bar_selector = '#build-pc-done-bar-%s' % build.id
+ bar_element = element.find_element_by_css_selector(bar_selector)
+
+ task_bar_updated = lambda driver: \
+ bar_element.get_attribute('style') == 'width: 50%;'
+ msg = 'tasks progress bar should update to 50%'
+ element = Wait(self.driver).until(task_bar_updated, msg)
+
+ # last task finished; check tasks progress bar updates
+ task2.order = 2
+ task2.save()
+
+ self.get(url)
+
+ element = self.wait_until_visible(selector)
+ bar_element = element.find_element_by_css_selector(bar_selector)
+ task_bar_updated = lambda driver: \
+ bar_element.get_attribute('style') == 'width: 100%;'
+ msg = 'tasks progress bar should update to 100%'
+ element = Wait(self.driver).until(task_bar_updated, msg)
+
+ def test_states_to_success(self):
+ """
+ Test state transitions in the recent builds area for a build which
+ completes successfully.
+ """
+ build_request = self._create_build_request()
+
+ self._check_build_states(build_request)
+
+ # all tasks complete and build succeeded; check success state shown
+ build = build_request.build
+ build.outcome = Build.SUCCEEDED
+ build.save()
+
+ selector = '[data-latest-build-result="%s"] ' \
+ '[data-build-state="Succeeded"]' % build.id
+ element = self.wait_until_visible(selector)
+
+ def test_states_to_failure(self):
+ """
+ Test state transitions in the recent builds area for a build which
+ completes in a failure.
+ """
+ build_request = self._create_build_request()
+
+ self._check_build_states(build_request)
+
+ # all tasks complete and build succeeded; check fail state shown
+ build = build_request.build
+ build.outcome = Build.FAILED
+ build.save()
+
+ selector = '[data-latest-build-result="%s"] ' \
+ '[data-build-state="Failed"]' % build.id
+ element = self.wait_until_visible(selector)
+
+ def test_states_cancelling(self):
+ """
+ Test that most recent build area updates correctly for a build
+ which is cancelled.
+ """
+ url = reverse('all-builds')
+
+ build_request = self._create_build_request()
+ build = build_request.build
+
+ # cancel the build
+ build_request.state = BuildRequest.REQ_CANCELLING
+ build_request.save()
+
+ self.get(url)
+
+ # check cancelling state
+ selector = '[data-latest-build-result="%s"] ' \
+ '[data-build-state="Cancelling"]' % build.id
+ element = self.wait_until_visible(selector)
+ self.assertRegexpMatches(element.get_attribute('innerHTML'),
+ 'Cancelling the build', 'build should show "cancelling" status')
+
+ # check cancelled state
+ build.outcome = Build.CANCELLED
+ build.save()
+
+ self.get(url)
+
+ selector = '[data-latest-build-result="%s"] ' \
+ '[data-build-state="Cancelled"]' % build.id
+ element = self.wait_until_visible(selector)
+ self.assertRegexpMatches(element.get_attribute('innerHTML'),
+ 'Build cancelled', 'build should show "cancelled" status')
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py
index 8906cb27d..ab5a8e66b 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py
@@ -25,6 +25,7 @@ from tests.browser.selenium_helpers import SeleniumTestCase
from orm.models import BitbakeVersion, Release, Project, ProjectLayer, Layer
from orm.models import Layer_Version, Recipe, CustomImageRecipe
+
class TestNewCustomImagePage(SeleniumTestCase):
CUSTOM_IMAGE_NAME = 'roopa-doopa'
@@ -140,7 +141,7 @@ class TestNewCustomImagePage(SeleniumTestCase):
self._create_custom_image(self.recipe.name)
element = self.wait_until_visible('#invalid-name-help')
self.assertRegexpMatches(element.text.strip(),
- 'recipe with this name already exists')
+ 'image with this name already exists')
def test_new_duplicates_project_image(self):
"""
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_project_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_project_page.py
new file mode 100644
index 000000000..77e5f1526
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_new_project_page.py
@@ -0,0 +1,113 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from django.core.urlresolvers import reverse
+from tests.browser.selenium_helpers import SeleniumTestCase
+from selenium.webdriver.support.ui import Select
+from selenium.common.exceptions import InvalidElementStateException
+
+from orm.models import Project, Release, BitbakeVersion
+
+
+class TestNewProjectPage(SeleniumTestCase):
+ """ Test project data at /project/X/ is displayed correctly """
+
+ def setUp(self):
+ bitbake, c = BitbakeVersion.objects.get_or_create(
+ name="master",
+ giturl="git://master",
+ branch="master",
+ dirpath="master")
+
+ release, c = Release.objects.get_or_create(name="msater",
+ description="master"
+ "release",
+ branch_name="master",
+ helptext="latest",
+ bitbake_version=bitbake)
+
+ self.release, c = Release.objects.get_or_create(
+ name="msater2",
+ description="master2"
+ "release2",
+ branch_name="master2",
+ helptext="latest2",
+ bitbake_version=bitbake)
+
+ def test_create_new_project(self):
+ """ Test creating a project """
+
+ project_name = "masterproject"
+
+ url = reverse('newproject')
+ self.get(url)
+
+ self.enter_text('#new-project-name', project_name)
+
+ select = Select(self.find('#projectversion'))
+ select.select_by_value(str(self.release.pk))
+
+ self.click("#create-project-button")
+
+ # We should get redirected to the new project's page with the
+ # notification at the top
+ element = self.wait_until_visible('#project-created-notification')
+
+ self.assertTrue(project_name in element.text,
+ "New project name not in new project notification")
+
+ self.assertTrue(Project.objects.filter(name=project_name).count(),
+ "New project not found in database")
+
+ def test_new_duplicates_project_name(self):
+ """
+ Should not be able to create a new project whose name is the same
+ as an existing project
+ """
+
+ project_name = "dupproject"
+
+ Project.objects.create_project(name=project_name,
+ release=self.release)
+
+ url = reverse('newproject')
+ self.get(url)
+
+ self.enter_text('#new-project-name', project_name)
+
+ select = Select(self.find('#projectversion'))
+ select.select_by_value(str(self.release.pk))
+
+ element = self.wait_until_visible('#hint-error-project-name')
+
+ self.assertTrue(("Project names must be unique" in element.text),
+ "Did not find unique project name error message")
+
+ # Try and click it anyway, if it submits we'll have a new project in
+ # the db and assert then
+ try:
+ self.click("#create-project-button")
+ except InvalidElementStateException:
+ pass
+
+ self.assertTrue(
+ (Project.objects.filter(name=project_name).count() == 1),
+ "New project not found in database")
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_config_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_config_page.py
new file mode 100644
index 000000000..071008499
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_config_page.py
@@ -0,0 +1,231 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import re
+
+from django.core.urlresolvers import reverse
+from django.utils import timezone
+from tests.browser.selenium_helpers import SeleniumTestCase
+
+from orm.models import BitbakeVersion, Release, Project, ProjectVariable
+
+class TestProjectConfigsPage(SeleniumTestCase):
+ """ Test data at /project/X/builds is displayed correctly """
+
+ PROJECT_NAME = 'test project'
+ INVALID_PATH_START_TEXT = 'The directory path should either start with a /'
+ INVALID_PATH_CHAR_TEXT = 'The directory path cannot include spaces or ' \
+ 'any of these characters'
+
+ def setUp(self):
+ bbv = BitbakeVersion.objects.create(name='bbv1', giturl='/tmp/',
+ branch='master', dirpath='')
+ release = Release.objects.create(name='release1',
+ bitbake_version=bbv)
+ self.project1 = Project.objects.create_project(name=self.PROJECT_NAME,
+ release=release)
+ self.project1.save()
+
+
+ def test_no_underscore_iamgefs_type(self):
+ """
+ Should not accept IMAGEFS_TYPE with an underscore
+ """
+
+ imagefs_type = "foo_bar"
+
+ ProjectVariable.objects.get_or_create(project = self.project1, name = "IMAGE_FSTYPES", value = "abcd ")
+ url = reverse('projectconf', args=(self.project1.id,));
+ self.get(url);
+
+ self.click('#change-image_fstypes-icon')
+
+ self.enter_text('#new-imagefs_types', imagefs_type)
+
+ element = self.wait_until_visible('#hintError-image-fs_type')
+
+ self.assertTrue(("A valid image type cannot include underscores" in element.text),
+ "Did not find underscore error message")
+
+
+ def test_checkbox_verification(self):
+ """
+ Should automatically check the checkbox if user enters value
+ text box, if value is there in the checkbox.
+ """
+ imagefs_type = "btrfs"
+
+ ProjectVariable.objects.get_or_create(project = self.project1, name = "IMAGE_FSTYPES", value = "abcd ")
+ url = reverse('projectconf', args=(self.project1.id,));
+ self.get(url);
+
+ self.click('#change-image_fstypes-icon')
+
+ self.enter_text('#new-imagefs_types', imagefs_type)
+
+ checkboxes = self.driver.find_elements_by_xpath("//input[@class='fs-checkbox-fstypes']")
+
+ for checkbox in checkboxes:
+ if checkbox.get_attribute("value") == "btrfs":
+ self.assertEqual(checkbox.is_selected(), True)
+
+
+ def test_textbox_with_checkbox_verification(self):
+ """
+ Should automatically add or remove value in textbox, if user checks
+ or unchecks checkboxes.
+ """
+
+ ProjectVariable.objects.get_or_create(project = self.project1, name = "IMAGE_FSTYPES", value = "abcd ")
+ url = reverse('projectconf', args=(self.project1.id,));
+ self.get(url);
+
+ self.click('#change-image_fstypes-icon')
+
+ self.wait_until_visible('#new-imagefs_types')
+
+ checkboxes_selector = '.fs-checkbox-fstypes'
+
+ self.wait_until_visible(checkboxes_selector)
+ checkboxes = self.find_all(checkboxes_selector)
+
+ for checkbox in checkboxes:
+ if checkbox.get_attribute("value") == "cpio":
+ checkbox.click()
+ element = self.driver.find_element_by_id('new-imagefs_types')
+
+ self.wait_until_visible('#new-imagefs_types')
+
+ self.assertTrue(("cpio" in element.get_attribute('value'),
+ "Imagefs not added into the textbox"))
+ checkbox.click()
+ self.assertTrue(("cpio" not in element.text),
+ "Image still present in the textbox")
+
+ def test_set_download_dir(self):
+ """
+ Validate the allowed and disallowed types in the directory field for
+ DL_DIR
+ """
+
+ ProjectVariable.objects.get_or_create(project=self.project1,
+ name='DL_DIR')
+ url = reverse('projectconf', args=(self.project1.id,))
+ self.get(url)
+
+ # activate the input to edit download dir
+ self.click('#change-dl_dir-icon')
+ self.wait_until_visible('#new-dl_dir')
+
+ # downloads dir path doesn't start with / or ${...}
+ self.enter_text('#new-dl_dir', 'home/foo')
+ element = self.wait_until_visible('#hintError-initialChar-dl_dir')
+
+ msg = 'downloads directory path starts with invalid character but ' \
+ 'treated as valid'
+ self.assertTrue((self.INVALID_PATH_START_TEXT in element.text), msg)
+
+ # downloads dir path has a space
+ self.driver.find_element_by_id('new-dl_dir').clear()
+ self.enter_text('#new-dl_dir', '/foo/bar a')
+
+ element = self.wait_until_visible('#hintError-dl_dir')
+ msg = 'downloads directory path characters invalid but treated as valid'
+ self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
+
+ # downloads dir path starts with ${...} but has a space
+ self.driver.find_element_by_id('new-dl_dir').clear()
+ self.enter_text('#new-dl_dir', '${TOPDIR}/down foo')
+
+ element = self.wait_until_visible('#hintError-dl_dir')
+ msg = 'downloads directory path characters invalid but treated as valid'
+ self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
+
+ # downloads dir path starts with /
+ self.driver.find_element_by_id('new-dl_dir').clear()
+ self.enter_text('#new-dl_dir', '/bar/foo')
+
+ hidden_element = self.driver.find_element_by_id('hintError-dl_dir')
+ self.assertEqual(hidden_element.is_displayed(), False,
+ 'downloads directory path valid but treated as invalid')
+
+ # downloads dir path starts with ${...}
+ self.driver.find_element_by_id('new-dl_dir').clear()
+ self.enter_text('#new-dl_dir', '${TOPDIR}/down')
+
+ hidden_element = self.driver.find_element_by_id('hintError-dl_dir')
+ self.assertEqual(hidden_element.is_displayed(), False,
+ 'downloads directory path valid but treated as invalid')
+
+ def test_set_sstate_dir(self):
+ """
+ Validate the allowed and disallowed types in the directory field for
+ SSTATE_DIR
+ """
+
+ ProjectVariable.objects.get_or_create(project=self.project1,
+ name='SSTATE_DIR')
+ url = reverse('projectconf', args=(self.project1.id,))
+ self.get(url)
+
+ self.click('#change-sstate_dir-icon')
+
+ self.wait_until_visible('#new-sstate_dir')
+
+ # path doesn't start with / or ${...}
+ self.enter_text('#new-sstate_dir', 'home/foo')
+ element = self.wait_until_visible('#hintError-initialChar-sstate_dir')
+
+ msg = 'sstate directory path starts with invalid character but ' \
+ 'treated as valid'
+ self.assertTrue((self.INVALID_PATH_START_TEXT in element.text), msg)
+
+ # path has a space
+ self.driver.find_element_by_id('new-sstate_dir').clear()
+ self.enter_text('#new-sstate_dir', '/foo/bar a')
+
+ element = self.wait_until_visible('#hintError-sstate_dir')
+ msg = 'sstate directory path characters invalid but treated as valid'
+ self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
+
+ # path starts with ${...} but has a space
+ self.driver.find_element_by_id('new-sstate_dir').clear()
+ self.enter_text('#new-sstate_dir', '${TOPDIR}/down foo')
+
+ element = self.wait_until_visible('#hintError-sstate_dir')
+ msg = 'sstate directory path characters invalid but treated as valid'
+ self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
+
+ # path starts with /
+ self.driver.find_element_by_id('new-sstate_dir').clear()
+ self.enter_text('#new-sstate_dir', '/bar/foo')
+
+ hidden_element = self.driver.find_element_by_id('hintError-sstate_dir')
+ self.assertEqual(hidden_element.is_displayed(), False,
+ 'sstate directory path valid but treated as invalid')
+
+ # paths starts with ${...}
+ self.driver.find_element_by_id('new-sstate_dir').clear()
+ self.enter_text('#new-sstate_dir', '${TOPDIR}/down')
+
+ hidden_element = self.driver.find_element_by_id('hintError-sstate_dir')
+ self.assertEqual(hidden_element.is_displayed(), False,
+ 'sstate directory path valid but treated as invalid') \ No newline at end of file
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_page.py
index 786bef1c6..018646332 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_page.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_project_page.py
@@ -55,5 +55,5 @@ class TestProjectPage(SeleniumTestCase):
self.get(url)
# check that we get a project page with the correct heading
- project_name = self.find('#project-name').text.strip()
+ project_name = self.find('.project-name').text.strip()
self.assertEqual(project_name, self.CLI_BUILDS_PROJECT_NAME)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_sample.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_sample.py
index 7bb8b97e8..20ec53c28 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_sample.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_sample.py
@@ -37,5 +37,5 @@ class TestSample(SeleniumTestCase):
def test_landing_page_has_brand(self):
url = reverse('landing')
self.get(url)
- brand_link = self.find('span.brand a')
+ brand_link = self.find('.toaster-navbar-brand a.brand')
self.assertEqual(brand_link.text.strip(), 'Toaster')
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_task_page.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_task_page.py
new file mode 100644
index 000000000..690d116cb
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_task_page.py
@@ -0,0 +1,76 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from django.core.urlresolvers import reverse
+from django.utils import timezone
+from tests.browser.selenium_helpers import SeleniumTestCase
+from orm.models import Project, Build, Layer, Layer_Version, Recipe, Target
+from orm.models import Task, Task_Dependency
+
+class TestTaskPage(SeleniumTestCase):
+ """ Test page which shows an individual task """
+ RECIPE_NAME = 'bar'
+ RECIPE_VERSION = '0.1'
+ TASK_NAME = 'do_da_doo_ron_ron'
+
+ def setUp(self):
+ now = timezone.now()
+
+ project = Project.objects.get_or_create_default_project()
+
+ self.build = Build.objects.create(project=project, started_on=now,
+ completed_on=now)
+
+ Target.objects.create(target='foo', build=self.build)
+
+ layer = Layer.objects.create()
+
+ layer_version = Layer_Version.objects.create(layer=layer)
+
+ recipe = Recipe.objects.create(name=TestTaskPage.RECIPE_NAME,
+ layer_version=layer_version, version=TestTaskPage.RECIPE_VERSION)
+
+ self.task = Task.objects.create(build=self.build, recipe=recipe,
+ order=1, outcome=Task.OUTCOME_COVERED, task_executed=False,
+ task_name=TestTaskPage.TASK_NAME)
+
+ def test_covered_task(self):
+ """
+ Check that covered tasks are displayed for tasks which have
+ dependencies on themselves
+ """
+
+ # the infinite loop which of bug 9952 was down to tasks which
+ # depend on themselves, so add self-dependent tasks to replicate the
+ # situation which caused the infinite loop (now fixed)
+ Task_Dependency.objects.create(task=self.task, depends_on=self.task)
+
+ url = reverse('task', args=(self.build.id, self.task.id,))
+ self.get(url)
+
+ # check that we see the task name
+ self.wait_until_visible('.page-header h1')
+
+ heading = self.find('.page-header h1')
+ expected_heading = '%s_%s %s' % (TestTaskPage.RECIPE_NAME,
+ TestTaskPage.RECIPE_VERSION, TestTaskPage.TASK_NAME)
+ self.assertEqual(heading.text, expected_heading,
+ 'Heading should show recipe name, version and task')
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_toastertable_ui.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_toastertable_ui.py
new file mode 100644
index 000000000..53ddf30c3
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/browser/test_toastertable_ui.py
@@ -0,0 +1,160 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2013-2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from datetime import datetime
+
+from django.core.urlresolvers import reverse
+from django.utils import timezone
+from tests.browser.selenium_helpers import SeleniumTestCase
+from orm.models import BitbakeVersion, Release, Project, Build
+
+class TestToasterTableUI(SeleniumTestCase):
+ """
+ Tests for the UI elements of ToasterTable (sorting etc.);
+ note that the tests cover generic functionality of ToasterTable which
+ manifests as UI elements in the browser, and can only be tested via
+ Selenium.
+ """
+
+ def setUp(self):
+ pass
+
+ def _get_orderby_heading(self, table):
+ """
+ Get the current order by finding the column heading in <table> with
+ the sorted class on it.
+
+ table: WebElement for a ToasterTable
+ """
+ selector = 'thead a.sorted'
+ heading = table.find_element_by_css_selector(selector)
+ return heading.get_attribute('innerHTML').strip()
+
+ def _get_datetime_from_cell(self, row, selector):
+ """
+ Return the value in the cell selected by <selector> on <row> as a
+ datetime.
+
+ row: <tr> WebElement for a row in the ToasterTable
+ selector: CSS selector to use to find the cell containing the date time
+ string
+ """
+ cell = row.find_element_by_css_selector(selector)
+ cell_text = cell.get_attribute('innerHTML').strip()
+ return datetime.strptime(cell_text, '%d/%m/%y %H:%M')
+
+ def test_revert_orderby(self):
+ """
+ Test that sort order for a table reverts to the default sort order
+ if the current sort column is hidden.
+ """
+ now = timezone.now()
+ later = now + timezone.timedelta(hours=1)
+ even_later = later + timezone.timedelta(hours=1)
+
+ bbv = BitbakeVersion.objects.create(name='test bbv', giturl='/tmp/',
+ branch='master', dirpath='')
+ release = Release.objects.create(name='test release',
+ branch_name='master',
+ bitbake_version=bbv)
+
+ project = Project.objects.create_project('project', release)
+
+ # set up two builds which will order differently when sorted by
+ # started_on or completed_on
+
+ # started first, finished last
+ build1 = Build.objects.create(project=project,
+ started_on=now,
+ completed_on=even_later,
+ outcome=Build.SUCCEEDED)
+
+ # started second, finished first
+ build2 = Build.objects.create(project=project,
+ started_on=later,
+ completed_on=later,
+ outcome=Build.SUCCEEDED)
+
+ url = reverse('all-builds')
+ self.get(url)
+ table = self.wait_until_visible('#allbuildstable')
+
+ # check ordering (default is by -completed_on); so build1 should be
+ # first as it finished last
+ active_heading = self._get_orderby_heading(table)
+ self.assertEqual(active_heading, 'Completed on',
+ 'table should be sorted by "Completed on" by default')
+
+ row_selector = '#allbuildstable tbody tr'
+ cell_selector = 'td.completed_on'
+
+ rows = self.find_all(row_selector)
+ row1_completed_on = self._get_datetime_from_cell(rows[0], cell_selector)
+ row2_completed_on = self._get_datetime_from_cell(rows[1], cell_selector)
+ self.assertTrue(row1_completed_on > row2_completed_on,
+ 'table should be sorted by -completed_on')
+
+ # turn on started_on column
+ self.click('#edit-columns-button')
+ self.click('#checkbox-started_on')
+
+ # sort by started_on column
+ links = table.find_elements_by_css_selector('th.started_on a')
+ for link in links:
+ if link.get_attribute('innerHTML').strip() == 'Started on':
+ link.click()
+ break
+
+ # wait for table data to reload in response to new sort
+ self.wait_until_visible('#allbuildstable')
+
+ # check ordering; build1 should be first
+ active_heading = self._get_orderby_heading(table)
+ self.assertEqual(active_heading, 'Started on',
+ 'table should be sorted by "Started on"')
+
+ cell_selector = 'td.started_on'
+
+ rows = self.find_all(row_selector)
+ row1_started_on = self._get_datetime_from_cell(rows[0], cell_selector)
+ row2_started_on = self._get_datetime_from_cell(rows[1], cell_selector)
+ self.assertTrue(row1_started_on < row2_started_on,
+ 'table should be sorted by started_on')
+
+ # turn off started_on column
+ self.click('#edit-columns-button')
+ self.click('#checkbox-started_on')
+
+ # wait for table data to reload in response to new sort
+ self.wait_until_visible('#allbuildstable')
+
+ # check ordering (should revert to completed_on); build2 should be first
+ active_heading = self._get_orderby_heading(table)
+ self.assertEqual(active_heading, 'Completed on',
+ 'table should be sorted by "Completed on" after hiding sort column')
+
+ cell_selector = 'td.completed_on'
+
+ rows = self.find_all(row_selector)
+ row1_completed_on = self._get_datetime_from_cell(rows[0], cell_selector)
+ row2_completed_on = self._get_datetime_from_cell(rows[1], cell_selector)
+ self.assertTrue(row1_completed_on > row2_completed_on,
+ 'table should be sorted by -completed_on')
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/README b/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/README
new file mode 100644
index 000000000..4a3b5328b
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/README
@@ -0,0 +1,14 @@
+# Running build tests
+
+These tests are to test the running of builds and the data produced by the builds.
+Your oe build environment must be sourced/initialised for these tests to run.
+
+The simplest way to run the tests are the following commands:
+
+$ . oe-init-build-env
+$ cd bitbake/lib/toaster/ # path my vary but this is into toaster's directory
+$ DJANGO_SETTINGS_MODULE='toastermain.settings_test' ./manage.py test tests.builds
+
+Optional environment variables:
+ - TOASTER_DIR (where toaster keeps it's artifacts)
+ - TOASTER_CONF a path to the toasterconf.json file. This will need to be set if you don't execute the tests from toaster's own directory.
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/__init__.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/__init__.py
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/buildtest.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/buildtest.py
new file mode 100644
index 000000000..fc7bd5b64
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/buildtest.py
@@ -0,0 +1,134 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import os
+import sys
+import time
+import unittest
+
+from orm.models import Project, Release, ProjectTarget, Build
+from bldcontrol.models import BuildEnvironment
+
+from bldcontrol.management.commands.loadconf import Command\
+ as LoadConfigCommand
+
+from bldcontrol.management.commands.runbuilds import Command\
+ as RunBuildsCommand
+
+import subprocess
+
+# We use unittest.TestCase instead of django.test.TestCase because we don't
+# want to wrap everything in a database transaction as an external process
+# (bitbake needs access to the database)
+
+
+class BuildTest(unittest.TestCase):
+
+ PROJECT_NAME = "Testbuild"
+
+ def build(self, target):
+ # So that the buildinfo helper uses the test database'
+ self.assertEqual(
+ os.environ.get('DJANGO_SETTINGS_MODULE', ''),
+ 'toastermain.settings-test',
+ "Please initialise django with the tests settings: "
+ "DJANGO_SETTINGS_MODULE='toastermain.settings-test'")
+
+ if self.target_already_built(target):
+ return
+
+ # Take a guess at the location of the toasterconf
+ poky_toaster_conf = '../../../meta-poky/conf/toasterconf.json'
+ oe_toaster_conf = '../../../meta/conf/toasterconf.json'
+ env_toaster_conf = os.environ.get('TOASTER_CONF')
+
+ config_file = None
+ if env_toaster_conf:
+ config_file = env_toaster_conf
+ else:
+ if os.path.exists(poky_toaster_conf):
+ config_file = poky_toaster_conf
+ elif os.path.exists(oe_toaster_conf):
+ config_file = oe_toaster_conf
+
+ self.assertIsNotNone(config_file,
+ "Default locations for toasterconf not found"
+ "please set $TOASTER_CONF manually")
+
+ # Setup the release information and default layers
+ print("\nImporting file: %s" % config_file)
+ os.environ['TOASTER_CONF'] = config_file
+ LoadConfigCommand()._import_layer_config(config_file)
+
+ os.environ['TOASTER_DIR'] = \
+ os.path.abspath(os.environ['BUILDDIR'] + "/../")
+
+ os.environ['BBBASEDIR'] = \
+ subprocess.check_output('which bitbake', shell=True)
+
+ BuildEnvironment.objects.get_or_create(
+ betype=BuildEnvironment.TYPE_LOCAL,
+ sourcedir=os.environ['TOASTER_DIR'],
+ builddir=os.environ['BUILDDIR']
+ )
+
+ release = Release.objects.get(name='local')
+
+ # Create a project for this build to run in
+ try:
+ project = Project.objects.get(name=BuildTest.PROJECT_NAME)
+ except Project.DoesNotExist:
+ project = Project.objects.create_project(
+ name=BuildTest.PROJECT_NAME,
+ release=release
+ )
+
+ ProjectTarget.objects.create(project=project,
+ target=target,
+ task="")
+ build_request = project.schedule_build()
+
+ # run runbuilds command to dispatch the build
+ # e.g. manage.py runubilds
+ RunBuildsCommand().runbuild()
+
+ build_pk = build_request.build.pk
+ while Build.objects.get(pk=build_pk).outcome == Build.IN_PROGRESS:
+ sys.stdout.write("\rBuilding %s %d%%" %
+ (target,
+ build_request.build.completeper()))
+ sys.stdout.flush()
+ time.sleep(1)
+
+ self.assertNotEqual(build_request.build.outcome,
+ Build.SUCCEEDED, "Build did not SUCCEEDED")
+ print("\nBuild finished")
+ return build_request.build
+
+ def target_already_built(self, target):
+ """ If the target is already built no need to build it again"""
+ for build in Build.objects.filter(
+ project__name=BuildTest.PROJECT_NAME):
+ targets = build.target_set.values_list('target', flat=True)
+ if target in targets:
+ return True
+
+ return False
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/test_core_image_min.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/test_core_image_min.py
new file mode 100644
index 000000000..dec0bfa7f
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/builds/test_core_image_min.py
@@ -0,0 +1,396 @@
+#! /usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Tests were part of openembedded-core oe selftest Authored by: Lucian Musat
+# Ionut Chisanovici, Paul Eggleton and Cristian Iorga
+
+import os
+
+from django.db.models import Q
+
+from orm.models import Target_Image_File, Target_Installed_Package, Task
+from orm.models import Package_Dependency, Recipe_Dependency, Build
+from orm.models import Task_Dependency, Package, Target, Recipe
+from orm.models import CustomImagePackage
+
+from buildtest import BuildTest
+
+
+class BuildCoreImageMinimal(BuildTest):
+ """Build core-image-minimal and test the results"""
+
+ def setUp(self):
+ self.build("core-image-minimal")
+
+ # Check if build name is unique - tc_id=795
+ def test_Build_Unique_Name(self):
+ all_builds = Build.objects.all().count()
+ distinct_builds = Build.objects.values('id').distinct().count()
+ self.assertEqual(distinct_builds,
+ all_builds,
+ msg='Build name is not unique')
+
+ # Check if build cooker log path is unique - tc_id=819
+ def test_Build_Unique_Cooker_Log_Path(self):
+ distinct_path = Build.objects.values(
+ 'cooker_log_path').distinct().count()
+ total_builds = Build.objects.values('id').count()
+ self.assertEqual(distinct_path,
+ total_builds,
+ msg='Build cooker log path is not unique')
+
+ # Check if task order is unique for one build - tc=824
+ def test_Task_Unique_Order(self):
+ builds = Build.objects.values('id')
+ cnt_err = []
+
+ for build in builds:
+ total_task_order = Task.objects.filter(
+ build=build['id']).values('order').count()
+ distinct_task_order = Task.objects.filter(
+ build=build['id']).values('order').distinct().count()
+
+ if (total_task_order != distinct_task_order):
+ cnt_err.append(build['id'])
+
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for build id: %s' % cnt_err)
+
+ # Check task order sequence for one build - tc=825
+ def test_Task_Order_Sequence(self):
+ builds = builds = Build.objects.values('id')
+ cnt_err = []
+ for build in builds:
+ tasks = Task.objects.filter(
+ Q(build=build['id']),
+ ~Q(order=None),
+ ~Q(task_name__contains='_setscene')
+ ).values('id', 'order').order_by("order")
+
+ cnt_tasks = 0
+ for task in tasks:
+ cnt_tasks += 1
+ if (task['order'] != cnt_tasks):
+ cnt_err.append(task['id'])
+ self.assertEqual(
+ len(cnt_err), 0, msg='Errors for task id: %s' % cnt_err)
+
+ # Check if disk_io matches the difference between EndTimeIO and
+ # StartTimeIO in build stats - tc=828
+ # def test_Task_Disk_IO_TC828(self):
+
+ # Check if outcome = 2 (SSTATE) then sstate_result must be 3 (RESTORED) -
+ # tc=832
+ def test_Task_If_Outcome_2_Sstate_Result_Must_Be_3(self):
+ tasks = Task.objects.filter(outcome=2).values('id', 'sstate_result')
+ cnt_err = []
+ for task in tasks:
+ if (task['sstate_result'] != 3):
+ cnt_err.append(task['id'])
+
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for task id: %s' % cnt_err)
+
+ # Check if outcome = 1 (COVERED) or 3 (EXISTING) then sstate_result must
+ # be 0 (SSTATE_NA) - tc=833
+ def test_Task_If_Outcome_1_3_Sstate_Result_Must_Be_0(self):
+ tasks = Task.objects.filter(
+ outcome__in=(Task.OUTCOME_COVERED,
+ Task.OUTCOME_PREBUILT)).values('id',
+ 'task_name',
+ 'sstate_result')
+ cnt_err = []
+
+ for task in tasks:
+ if (task['sstate_result'] != Task.SSTATE_NA and
+ task['sstate_result'] != Task.SSTATE_MISS):
+ cnt_err.append({'id': task['id'],
+ 'name': task['task_name'],
+ 'sstate_result': task['sstate_result'],
+ })
+
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for task id: %s' % cnt_err)
+
+ # Check if outcome is 0 (SUCCESS) or 4 (FAILED) then sstate_result must be
+ # 0 (NA), 1 (MISS) or 2 (FAILED) - tc=834
+ def test_Task_If_Outcome_0_4_Sstate_Result_Must_Be_0_1_2(self):
+ tasks = Task.objects.filter(
+ outcome__in=(0, 4)).values('id', 'sstate_result')
+ cnt_err = []
+
+ for task in tasks:
+ if (task['sstate_result'] not in [0, 1, 2]):
+ cnt_err.append(task['id'])
+
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for task id: %s' % cnt_err)
+
+ # Check if task_executed = TRUE (1), script_type must be 0 (CODING_NA), 2
+ # (CODING_PYTHON), 3 (CODING_SHELL) - tc=891
+ def test_Task_If_Task_Executed_True_Script_Type_0_2_3(self):
+ tasks = Task.objects.filter(
+ task_executed=1).values('id', 'script_type')
+ cnt_err = []
+
+ for task in tasks:
+ if (task['script_type'] not in [0, 2, 3]):
+ cnt_err.append(task['id'])
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for task id: %s' % cnt_err)
+
+ # Check if task_executed = TRUE (1), outcome must be 0 (SUCCESS) or 4
+ # (FAILED) - tc=836
+ def test_Task_If_Task_Executed_True_Outcome_0_4(self):
+ tasks = Task.objects.filter(task_executed=1).values('id', 'outcome')
+ cnt_err = []
+
+ for task in tasks:
+ if (task['outcome'] not in [0, 4]):
+ cnt_err.append(task['id'])
+
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for task id: %s' % cnt_err)
+
+ # Check if task_executed = FALSE (0), script_type must be 0 - tc=890
+ def test_Task_If_Task_Executed_False_Script_Type_0(self):
+ tasks = Task.objects.filter(
+ task_executed=0).values('id', 'script_type')
+ cnt_err = []
+
+ for task in tasks:
+ if (task['script_type'] != 0):
+ cnt_err.append(task['id'])
+
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for task id: %s' % cnt_err)
+
+ # Check if task_executed = FALSE (0) and build outcome = SUCCEEDED (0),
+ # task outcome must be 1 (COVERED), 2 (CACHED), 3 (PREBUILT), 5 (EMPTY) -
+ # tc=837
+ def test_Task_If_Task_Executed_False_Outcome_1_2_3_5(self):
+ builds = Build.objects.filter(outcome=0).values('id')
+ cnt_err = []
+ for build in builds:
+ tasks = Task.objects.filter(
+ build=build['id'], task_executed=0).values('id', 'outcome')
+ for task in tasks:
+ if (task['outcome'] not in [1, 2, 3, 5]):
+ cnt_err.append(task['id'])
+
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for task id: %s' % cnt_err)
+
+ # Key verification - tc=888
+ def test_Target_Installed_Package(self):
+ rows = Target_Installed_Package.objects.values('id',
+ 'target_id',
+ 'package_id')
+ cnt_err = []
+
+ for row in rows:
+ target = Target.objects.filter(id=row['target_id']).values('id')
+ package = Package.objects.filter(id=row['package_id']).values('id')
+ if (not target or not package):
+ cnt_err.append(row['id'])
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for target installed package id: %s' %
+ cnt_err)
+
+ # Key verification - tc=889
+ def test_Task_Dependency(self):
+ rows = Task_Dependency.objects.values('id',
+ 'task_id',
+ 'depends_on_id')
+ cnt_err = []
+ for row in rows:
+ task_id = Task.objects.filter(id=row['task_id']).values('id')
+ depends_on_id = Task.objects.filter(
+ id=row['depends_on_id']).values('id')
+ if (not task_id or not depends_on_id):
+ cnt_err.append(row['id'])
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg='Errors for task dependency id: %s' % cnt_err)
+
+ # Check if build target file_name is populated only if is_image=true AND
+ # orm_build.outcome=0 then if the file exists and its size matches
+ # the file_size value. Need to add the tc in the test run
+ def test_Target_File_Name_Populated(self):
+ builds = Build.objects.filter(outcome=0).values('id')
+ for build in builds:
+ targets = Target.objects.filter(
+ build_id=build['id'], is_image=1).values('id')
+ for target in targets:
+ target_files = Target_Image_File.objects.filter(
+ target_id=target['id']).values('id',
+ 'file_name',
+ 'file_size')
+ cnt_err = []
+ for file_info in target_files:
+ target_id = file_info['id']
+ target_file_name = file_info['file_name']
+ target_file_size = file_info['file_size']
+ if (not target_file_name or not target_file_size):
+ cnt_err.append(target_id)
+ else:
+ if (not os.path.exists(target_file_name)):
+ cnt_err.append(target_id)
+ else:
+ if (os.path.getsize(target_file_name) !=
+ target_file_size):
+ cnt_err.append(target_id)
+ self.assertEqual(len(cnt_err), 0,
+ msg='Errors for target image file id: %s' %
+ cnt_err)
+
+ # Key verification - tc=884
+ def test_Package_Dependency(self):
+ cnt_err = []
+ deps = Package_Dependency.objects.values(
+ 'id', 'package_id', 'depends_on_id')
+ for dep in deps:
+ if (dep['package_id'] == dep['depends_on_id']):
+ cnt_err.append(dep['id'])
+ self.assertEqual(len(cnt_err), 0,
+ msg='Errors for package dependency id: %s' % cnt_err)
+
+ # Recipe key verification, recipe name does not depends on a recipe having
+ # the same name - tc=883
+ def test_Recipe_Dependency(self):
+ deps = Recipe_Dependency.objects.values(
+ 'id', 'recipe_id', 'depends_on_id')
+ cnt_err = []
+ for dep in deps:
+ if (not dep['recipe_id'] or not dep['depends_on_id']):
+ cnt_err.append(dep['id'])
+ else:
+ name = Recipe.objects.filter(
+ id=dep['recipe_id']).values('name')
+ dep_name = Recipe.objects.filter(
+ id=dep['depends_on_id']).values('name')
+ if (name == dep_name):
+ cnt_err.append(dep['id'])
+ self.assertEqual(len(cnt_err), 0,
+ msg='Errors for recipe dependency id: %s' % cnt_err)
+
+ # Check if package name does not start with a number (0-9) - tc=846
+ def test_Package_Name_For_Number(self):
+ packages = Package.objects.filter(~Q(size=-1)).values('id', 'name')
+ cnt_err = []
+ for package in packages:
+ if (package['name'][0].isdigit() is True):
+ cnt_err.append(package['id'])
+ self.assertEqual(
+ len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
+
+ # Check if package version starts with a number (0-9) - tc=847
+ def test_Package_Version_Starts_With_Number(self):
+ packages = Package.objects.filter(
+ ~Q(size=-1)).values('id', 'version')
+ cnt_err = []
+ for package in packages:
+ if (package['version'][0].isdigit() is False):
+ cnt_err.append(package['id'])
+ self.assertEqual(
+ len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
+
+ # Check if package revision starts with 'r' - tc=848
+ def test_Package_Revision_Starts_With_r(self):
+ packages = Package.objects.filter(
+ ~Q(size=-1)).values('id', 'revision')
+ cnt_err = []
+ for package in packages:
+ if (package['revision'][0].startswith("r") is False):
+ cnt_err.append(package['id'])
+ self.assertEqual(
+ len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
+
+ # Check the validity of the package build_id
+ # TC must be added in test run
+ def test_Package_Build_Id(self):
+ packages = Package.objects.filter(
+ ~Q(size=-1)).values('id', 'build_id')
+ cnt_err = []
+ for package in packages:
+ build_id = Build.objects.filter(
+ id=package['build_id']).values('id')
+ if (not build_id):
+ # They have no build_id but if they are
+ # CustomImagePackage that's expected
+ try:
+ CustomImagePackage.objects.get(pk=package['id'])
+ except CustomImagePackage.DoesNotExist:
+ cnt_err.append(package['id'])
+
+ self.assertEqual(len(cnt_err),
+ 0,
+ msg="Errors for package id: %s they have no build"
+ "associated with them" % cnt_err)
+
+ # Check the validity of package recipe_id
+ # TC must be added in test run
+ def test_Package_Recipe_Id(self):
+ packages = Package.objects.filter(
+ ~Q(size=-1)).values('id', 'recipe_id')
+ cnt_err = []
+ for package in packages:
+ recipe_id = Recipe.objects.filter(
+ id=package['recipe_id']).values('id')
+ if (not recipe_id):
+ cnt_err.append(package['id'])
+ self.assertEqual(
+ len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
+
+ # Check if package installed_size field is not null
+ # TC must be aded in test run
+ def test_Package_Installed_Size_Not_NULL(self):
+ packages = Package.objects.filter(
+ installed_size__isnull=True).values('id')
+ cnt_err = []
+ for package in packages:
+ cnt_err.append(package['id'])
+ self.assertEqual(
+ len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
+
+ def test_custom_packages_generated(self):
+ """Test if there is a corresponding generated CustomImagePackage"""
+ """ for each of the packages generated"""
+ missing_packages = []
+
+ for package in Package.objects.all():
+ try:
+ CustomImagePackage.objects.get(name=package.name)
+ except CustomImagePackage.DoesNotExist:
+ missing_packages.append(package.name)
+
+ self.assertEqual(len(missing_packages), 0,
+ "Some package were created from the build but their"
+ " corresponding CustomImagePackage was not found")
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/db/__init__.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/db/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/db/__init__.py
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/db/test_db.py b/import-layers/yocto-poky/bitbake/lib/toaster/tests/db/test_db.py
new file mode 100644
index 000000000..a0f5f6ec0
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/db/test_db.py
@@ -0,0 +1,55 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2016 Damien Lespiau
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import sys
+
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+
+from contextlib import contextmanager
+
+from django.core import management
+from django.test import TestCase
+
+
+@contextmanager
+def capture(command, *args, **kwargs):
+ out, sys.stdout = sys.stdout, StringIO()
+ command(*args, **kwargs)
+ sys.stdout.seek(0)
+ yield sys.stdout.read()
+ sys.stdout = out
+
+
+def makemigrations():
+ management.call_command('makemigrations')
+
+
+class MigrationTest(TestCase):
+
+ def testPendingMigration(self):
+ """Make sure there's no pending migration."""
+
+ with capture(makemigrations) as output:
+ self.assertEqual(output, "No changes detected\n")
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/tests/functional/README b/import-layers/yocto-poky/bitbake/lib/toaster/tests/functional/README
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/tests/functional/README
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/api.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/api.py
index 42901f750..ae1f15077 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/api.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/api.py
@@ -16,14 +16,32 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# Please run flake8 on this file before sending patches
-# Temporary home for the UI's misc API
+import re
+import logging
+from collections import Counter
-from orm.models import Project, ProjectTarget, Build
+from orm.models import Project, ProjectTarget, Build, Layer_Version
+from orm.models import LayerVersionDependency, LayerSource, ProjectLayer
+from orm.models import Recipe, CustomImageRecipe, CustomImagePackage
+from orm.models import Layer, Target, Package, Package_Dependency
+from orm.models import ProjectVariable
from bldcontrol.models import BuildRequest
from bldcontrol import bbcontroller
+
from django.http import HttpResponse, JsonResponse
from django.views.generic import View
+from django.core.urlresolvers import reverse
+from django.db.models import Q, F
+from django.db import Error
+from toastergui.templatetags.projecttags import filtered_filesizeformat
+
+logger = logging.getLogger("toaster")
+
+
+def error_response(error):
+ return JsonResponse({"error": error})
class XhrBuildRequest(View):
@@ -31,6 +49,28 @@ class XhrBuildRequest(View):
def get(self, request, *args, **kwargs):
return HttpResponse()
+ @staticmethod
+ def cancel_build(br):
+ """Cancel a build request"""
+ try:
+ bbctrl = bbcontroller.BitbakeController(br.environment)
+ bbctrl.forceShutDown()
+ except:
+ # We catch a bunch of exceptions here because
+ # this is where the server has not had time to start up
+ # and the build request or build is in transit between
+ # processes.
+ # We can safely just set the build as cancelled
+ # already as it never got started
+ build = br.build
+ build.outcome = Build.CANCELLED
+ build.save()
+
+ # We now hand over to the buildinfohelper to update the
+ # build state once we've finished cancelling
+ br.state = BuildRequest.REQ_CANCELLING
+ br.save()
+
def post(self, request, *args, **kwargs):
"""
Build control
@@ -56,55 +96,782 @@ class XhrBuildRequest(View):
for i in request.POST['buildCancel'].strip().split(" "):
try:
br = BuildRequest.objects.get(project=project, pk=i)
-
- try:
- bbctrl = bbcontroller.BitbakeController(br.environment)
- bbctrl.forceShutDown()
- except:
- # We catch a bunch of exceptions here because
- # this is where the server has not had time to start up
- # and the build request or build is in transit between
- # processes.
- # We can safely just set the build as cancelled
- # already as it never got started
- build = br.build
- build.outcome = Build.CANCELLED
- build.save()
-
- # We now hand over to the buildinfohelper to update the
- # build state once we've finished cancelling
- br.state = BuildRequest.REQ_CANCELLING
- br.save()
-
+ self.cancel_build(br)
except BuildRequest.DoesNotExist:
- return JsonResponse({'error':'No such build id %s' % i})
+ return error_response('No such build request id %s' % i)
- return JsonResponse({'error': 'ok'})
+ return error_response('ok')
if 'buildDelete' in request.POST:
for i in request.POST['buildDelete'].strip().split(" "):
try:
- BuildRequest.objects.select_for_update().get(project = project, pk = i, state__lte = BuildRequest.REQ_DELETED).delete()
+ BuildRequest.objects.select_for_update().get(
+ project=project,
+ pk=i,
+ state__lte=BuildRequest.REQ_DELETED).delete()
+
except BuildRequest.DoesNotExist:
pass
- return JsonResponse({'error': 'ok' })
+ return error_response("ok")
if 'targets' in request.POST:
- ProjectTarget.objects.filter(project = project).delete()
+ ProjectTarget.objects.filter(project=project).delete()
s = str(request.POST['targets'])
- for t in s.translate(None, ";%|\"").split(" "):
+ for t in re.sub(r'[;%|"]', '', s).split(" "):
if ":" in t:
target, task = t.split(":")
else:
target = t
task = ""
- ProjectTarget.objects.create(project = project,
- target = target,
- task = task)
+ ProjectTarget.objects.create(project=project,
+ target=target,
+ task=task)
project.schedule_build()
- return JsonResponse({'error': 'ok' })
+ return error_response('ok')
response = HttpResponse()
response.status_code = 500
return response
+
+
+class XhrLayer(View):
+ """ Get and Update Layer information """
+
+ def post(self, request, *args, **kwargs):
+ """
+ Update a layer
+
+ Entry point: /xhr_layer/<layerversion_id>
+ Method: POST
+
+ Args:
+ vcs_url, dirpath, commit, up_branch, summary, description,
+ local_source_dir
+
+ add_dep = append a layerversion_id as a dependency
+ rm_dep = remove a layerversion_id as a depedency
+ Returns:
+ {"error": "ok"}
+ or
+ {"error": <error message>}
+ """
+
+ try:
+ # We currently only allow Imported layers to be edited
+ layer_version = Layer_Version.objects.get(
+ id=kwargs['layerversion_id'],
+ project=kwargs['pid'],
+ layer_source=LayerSource.TYPE_IMPORTED)
+
+ except Layer_Version.DoesNotExist:
+ return error_response("Cannot find imported layer to update")
+
+ if "vcs_url" in request.POST:
+ layer_version.layer.vcs_url = request.POST["vcs_url"]
+ if "dirpath" in request.POST:
+ layer_version.dirpath = request.POST["dirpath"]
+ if "commit" in request.POST:
+ layer_version.commit = request.POST["commit"]
+ layer_version.branch = request.POST["commit"]
+ if "summary" in request.POST:
+ layer_version.layer.summary = request.POST["summary"]
+ if "description" in request.POST:
+ layer_version.layer.description = request.POST["description"]
+ if "local_source_dir" in request.POST:
+ layer_version.layer.local_source_dir = \
+ request.POST["local_source_dir"]
+
+ if "add_dep" in request.POST:
+ lvd = LayerVersionDependency(
+ layer_version=layer_version,
+ depends_on_id=request.POST["add_dep"])
+ lvd.save()
+
+ if "rm_dep" in request.POST:
+ rm_dep = LayerVersionDependency.objects.get(
+ layer_version=layer_version,
+ depends_on_id=request.POST["rm_dep"])
+ rm_dep.delete()
+
+ try:
+ layer_version.layer.save()
+ layer_version.save()
+ except Exception as e:
+ return error_response("Could not update layer version entry: %s"
+ % e)
+
+ return JsonResponse({"error": "ok"})
+
+ def delete(self, request, *args, **kwargs):
+ try:
+ # We currently only allow Imported layers to be deleted
+ layer_version = Layer_Version.objects.get(
+ id=kwargs['layerversion_id'],
+ project=kwargs['pid'],
+ layer_source=LayerSource.TYPE_IMPORTED)
+ except Layer_Version.DoesNotExist:
+ return error_response("Cannot find imported layer to delete")
+
+ try:
+ ProjectLayer.objects.get(project=kwargs['pid'],
+ layercommit=layer_version).delete()
+ except ProjectLayer.DoesNotExist:
+ pass
+
+ layer_version.layer.delete()
+ layer_version.delete()
+
+ return JsonResponse({
+ "error": "ok",
+ "gotoUrl": reverse('projectlayers', args=(kwargs['pid'],))
+ })
+
+
+class XhrCustomRecipe(View):
+ """ Create a custom image recipe """
+
+ def post(self, request, *args, **kwargs):
+ """
+ Custom image recipe REST API
+
+ Entry point: /xhr_customrecipe/
+ Method: POST
+
+ Args:
+ name: name of custom recipe to create
+ project: target project id of orm.models.Project
+ base: base recipe id of orm.models.Recipe
+
+ Returns:
+ {"error": "ok",
+ "url": <url of the created recipe>}
+ or
+ {"error": <error message>}
+ """
+ # check if request has all required parameters
+ for param in ('name', 'project', 'base'):
+ if param not in request.POST:
+ return error_response("Missing parameter '%s'" % param)
+
+ # get project and baserecipe objects
+ params = {}
+ for name, model in [("project", Project),
+ ("base", Recipe)]:
+ value = request.POST[name]
+ try:
+ params[name] = model.objects.get(id=value)
+ except model.DoesNotExist:
+ return error_response("Invalid %s id %s" % (name, value))
+
+ # create custom recipe
+ try:
+
+ # Only allowed chars in name are a-z, 0-9 and -
+ if re.search(r'[^a-z|0-9|-]', request.POST["name"]):
+ return error_response("invalid-name")
+
+ custom_images = CustomImageRecipe.objects.all()
+
+ # Are there any recipes with this name already in our project?
+ existing_image_recipes_in_project = custom_images.filter(
+ name=request.POST["name"], project=params["project"])
+
+ if existing_image_recipes_in_project.count() > 0:
+ return error_response("image-already-exists")
+
+ # Are there any recipes with this name which aren't custom
+ # image recipes?
+ custom_image_ids = custom_images.values_list('id', flat=True)
+ existing_non_image_recipes = Recipe.objects.filter(
+ Q(name=request.POST["name"]) & ~Q(pk__in=custom_image_ids)
+ )
+
+ if existing_non_image_recipes.count() > 0:
+ return error_response("recipe-already-exists")
+
+ # create layer 'Custom layer' and verion if needed
+ layer = Layer.objects.get_or_create(
+ name=CustomImageRecipe.LAYER_NAME,
+ summary="Layer for custom recipes",
+ vcs_url="file:///toaster_created_layer")[0]
+
+ # Check if we have a layer version already
+ # We don't use get_or_create here because the dirpath will change
+ # and is a required field
+ lver = Layer_Version.objects.filter(Q(project=params['project']) &
+ Q(layer=layer) &
+ Q(build=None)).last()
+ if lver is None:
+ lver, created = Layer_Version.objects.get_or_create(
+ project=params['project'],
+ layer=layer,
+ dirpath="toaster_created_layer")
+
+ # Add a dependency on our layer to the base recipe's layer
+ LayerVersionDependency.objects.get_or_create(
+ layer_version=lver,
+ depends_on=params["base"].layer_version)
+
+ # Add it to our current project if needed
+ ProjectLayer.objects.get_or_create(project=params['project'],
+ layercommit=lver,
+ optional=False)
+
+ # Create the actual recipe
+ recipe, created = CustomImageRecipe.objects.get_or_create(
+ name=request.POST["name"],
+ base_recipe=params["base"],
+ project=params["project"],
+ layer_version=lver,
+ is_image=True)
+
+ # If we created the object then setup these fields. They may get
+ # overwritten later on and cause the get_or_create to create a
+ # duplicate if they've changed.
+ if created:
+ recipe.file_path = request.POST["name"]
+ recipe.license = "MIT"
+ recipe.version = "0.1"
+ recipe.save()
+
+ except Error as err:
+ return error_response("Can't create custom recipe: %s" % err)
+
+ # Find the package list from the last build of this recipe/target
+ target = Target.objects.filter(Q(build__outcome=Build.SUCCEEDED) &
+ Q(build__project=params['project']) &
+ (Q(target=params['base'].name) |
+ Q(target=recipe.name))).last()
+ if target:
+ # Copy in every package
+ # We don't want these packages to be linked to anything because
+ # that underlying data may change e.g. delete a build
+ for tpackage in target.target_installed_package_set.all():
+ try:
+ built_package = tpackage.package
+ # The package had no recipe information so is a ghost
+ # package skip it
+ if built_package.recipe is None:
+ continue
+
+ config_package = CustomImagePackage.objects.get(
+ name=built_package.name)
+
+ recipe.includes_set.add(config_package)
+ except Exception as e:
+ logger.warning("Error adding package %s %s" %
+ (tpackage.package.name, e))
+ pass
+
+ return JsonResponse(
+ {"error": "ok",
+ "packages": recipe.get_all_packages().count(),
+ "url": reverse('customrecipe', args=(params['project'].pk,
+ recipe.id))})
+
+
+class XhrCustomRecipeId(View):
+ """
+ Set of ReST API processors working with recipe id.
+
+ Entry point: /xhr_customrecipe/<recipe_id>
+
+ Methods:
+ GET - Get details of custom image recipe
+ DELETE - Delete custom image recipe
+
+ Returns:
+ GET:
+ {"error": "ok",
+ "info": dictionary of field name -> value pairs
+ of the CustomImageRecipe model}
+ DELETE:
+ {"error": "ok"}
+ or
+ {"error": <error message>}
+ """
+ @staticmethod
+ def _get_ci_recipe(recipe_id):
+ """ Get Custom Image recipe or return an error response"""
+ try:
+ custom_recipe = \
+ CustomImageRecipe.objects.get(pk=recipe_id)
+ return custom_recipe, None
+
+ except CustomImageRecipe.DoesNotExist:
+ return None, error_response("Custom recipe with id=%s "
+ "not found" % recipe_id)
+
+ def get(self, request, *args, **kwargs):
+ custom_recipe, error = self._get_ci_recipe(kwargs['recipe_id'])
+ if error:
+ return error
+
+ if request.method == 'GET':
+ info = {"id": custom_recipe.id,
+ "name": custom_recipe.name,
+ "base_recipe_id": custom_recipe.base_recipe.id,
+ "project_id": custom_recipe.project.id}
+
+ return JsonResponse({"error": "ok", "info": info})
+
+ def delete(self, request, *args, **kwargs):
+ custom_recipe, error = self._get_ci_recipe(kwargs['recipe_id'])
+ if error:
+ return error
+
+ project = custom_recipe.project
+
+ custom_recipe.delete()
+ return JsonResponse({"error": "ok",
+ "gotoUrl": reverse("projectcustomimages",
+ args=(project.pk,))})
+
+
+class XhrCustomRecipePackages(View):
+ """
+ ReST API to add/remove packages to/from custom recipe.
+
+ Entry point: /xhr_customrecipe/<recipe_id>/packages/<package_id>
+ Methods:
+ PUT - Add package to the recipe
+ DELETE - Delete package from the recipe
+ GET - Get package information
+
+ Returns:
+ {"error": "ok"}
+ or
+ {"error": <error message>}
+ """
+ @staticmethod
+ def _get_package(package_id):
+ try:
+ package = CustomImagePackage.objects.get(pk=package_id)
+ return package, None
+ except Package.DoesNotExist:
+ return None, error_response("Package with id=%s "
+ "not found" % package_id)
+
+ def _traverse_dependents(self, next_package_id,
+ rev_deps, all_current_packages, tree_level=0):
+ """
+ Recurse through reverse dependency tree for next_package_id.
+ Limit the reverse dependency search to packages not already scanned,
+ that is, not already in rev_deps.
+ Limit the scan to a depth (tree_level) not exceeding the count of
+ all packages in the custom image, and if that depth is exceeded
+ return False, pop out of the recursion, and write a warning
+ to the log, but this is unlikely, suggesting a dependency loop
+ not caught by bitbake.
+ On return, the input/output arg rev_deps is appended with queryset
+ dictionary elements, annotated for use in the customimage template.
+ The list has unsorted, but unique elements.
+ """
+ max_dependency_tree_depth = all_current_packages.count()
+ if tree_level >= max_dependency_tree_depth:
+ logger.warning(
+ "The number of reverse dependencies "
+ "for this package exceeds " + max_dependency_tree_depth +
+ " and the remaining reverse dependencies will not be removed")
+ return True
+
+ package = CustomImagePackage.objects.get(id=next_package_id)
+ dependents = \
+ package.package_dependencies_target.annotate(
+ name=F('package__name'),
+ pk=F('package__pk'),
+ size=F('package__size'),
+ ).values("name", "pk", "size").exclude(
+ ~Q(pk__in=all_current_packages)
+ )
+
+ for pkg in dependents:
+ if pkg in rev_deps:
+ # already seen, skip dependent search
+ continue
+
+ rev_deps.append(pkg)
+ if (self._traverse_dependents(pkg["pk"], rev_deps,
+ all_current_packages,
+ tree_level+1)):
+ return True
+
+ return False
+
+ def _get_all_dependents(self, package_id, all_current_packages):
+ """
+ Returns sorted list of recursive reverse dependencies for package_id,
+ as a list of dictionary items, by recursing through dependency
+ relationships.
+ """
+ rev_deps = []
+ self._traverse_dependents(package_id, rev_deps, all_current_packages)
+ rev_deps = sorted(rev_deps, key=lambda x: x["name"])
+ return rev_deps
+
+ def get(self, request, *args, **kwargs):
+ recipe, error = XhrCustomRecipeId._get_ci_recipe(
+ kwargs['recipe_id'])
+ if error:
+ return error
+
+ # If no package_id then list all the current packages
+ if not kwargs['package_id']:
+ total_size = 0
+ packages = recipe.get_all_packages().values("id",
+ "name",
+ "version",
+ "size")
+ for package in packages:
+ package['size_formatted'] = \
+ filtered_filesizeformat(package['size'])
+ total_size += package['size']
+
+ return JsonResponse({"error": "ok",
+ "packages": list(packages),
+ "total": len(packages),
+ "total_size": total_size,
+ "total_size_formatted":
+ filtered_filesizeformat(total_size)})
+ else:
+ package, error = XhrCustomRecipePackages._get_package(
+ kwargs['package_id'])
+ if error:
+ return error
+
+ all_current_packages = recipe.get_all_packages()
+
+ # Dependencies for package which aren't satisfied by the
+ # current packages in the custom image recipe
+ deps = package.package_dependencies_source.for_target_or_none(
+ recipe.name)['packages'].annotate(
+ name=F('depends_on__name'),
+ pk=F('depends_on__pk'),
+ size=F('depends_on__size'),
+ ).values("name", "pk", "size").filter(
+ # There are two depends types we don't know why
+ (Q(dep_type=Package_Dependency.TYPE_TRDEPENDS) |
+ Q(dep_type=Package_Dependency.TYPE_RDEPENDS)) &
+ ~Q(pk__in=all_current_packages)
+ )
+
+ # Reverse dependencies which are needed by packages that are
+ # in the image. Recursive search providing all dependents,
+ # not just immediate dependents.
+ reverse_deps = self._get_all_dependents(kwargs['package_id'],
+ all_current_packages)
+ total_size_deps = 0
+ total_size_reverse_deps = 0
+
+ for dep in deps:
+ dep['size_formatted'] = \
+ filtered_filesizeformat(dep['size'])
+ total_size_deps += dep['size']
+
+ for dep in reverse_deps:
+ dep['size_formatted'] = \
+ filtered_filesizeformat(dep['size'])
+ total_size_reverse_deps += dep['size']
+
+ return JsonResponse(
+ {"error": "ok",
+ "id": package.pk,
+ "name": package.name,
+ "version": package.version,
+ "unsatisfied_dependencies": list(deps),
+ "unsatisfied_dependencies_size": total_size_deps,
+ "unsatisfied_dependencies_size_formatted":
+ filtered_filesizeformat(total_size_deps),
+ "reverse_dependencies": list(reverse_deps),
+ "reverse_dependencies_size": total_size_reverse_deps,
+ "reverse_dependencies_size_formatted":
+ filtered_filesizeformat(total_size_reverse_deps)})
+
+ def put(self, request, *args, **kwargs):
+ recipe, error = XhrCustomRecipeId._get_ci_recipe(kwargs['recipe_id'])
+ package, error = self._get_package(kwargs['package_id'])
+ if error:
+ return error
+
+ included_packages = recipe.includes_set.values_list('pk',
+ flat=True)
+
+ # If we're adding back a package which used to be included in this
+ # image all we need to do is remove it from the excludes
+ if package.pk in included_packages:
+ try:
+ recipe.excludes_set.remove(package)
+ return {"error": "ok"}
+ except Package.DoesNotExist:
+ return error_response("Package %s not found in excludes"
+ " but was in included list" %
+ package.name)
+
+ else:
+ recipe.appends_set.add(package)
+ # Make sure that package is not in the excludes set
+ try:
+ recipe.excludes_set.remove(package)
+ except:
+ pass
+ # Add the dependencies we think will be added to the recipe
+ # as a result of appending this package.
+ # TODO this should recurse down the entire deps tree
+ for dep in package.package_dependencies_source.all_depends():
+ try:
+ cust_package = CustomImagePackage.objects.get(
+ name=dep.depends_on.name)
+
+ recipe.includes_set.add(cust_package)
+ try:
+ # When adding the pre-requisite package, make
+ # sure it's not in the excluded list from a
+ # prior removal.
+ recipe.excludes_set.remove(cust_package)
+ except package.DoesNotExist:
+ # Don't care if the package had never been excluded
+ pass
+ except:
+ logger.warning("Could not add package's suggested"
+ "dependencies to the list")
+ return JsonResponse({"error": "ok"})
+
+ def delete(self, request, *args, **kwargs):
+ recipe, error = XhrCustomRecipeId._get_ci_recipe(kwargs['recipe_id'])
+ package, error = self._get_package(kwargs['package_id'])
+ if error:
+ return error
+
+ try:
+ included_packages = recipe.includes_set.values_list('pk',
+ flat=True)
+ # If we're deleting a package which is included we need to
+ # Add it to the excludes list.
+ if package.pk in included_packages:
+ recipe.excludes_set.add(package)
+ else:
+ recipe.appends_set.remove(package)
+ all_current_packages = recipe.get_all_packages()
+
+ reverse_deps_dictlist = self._get_all_dependents(
+ package.pk,
+ all_current_packages)
+
+ ids = [entry['pk'] for entry in reverse_deps_dictlist]
+ reverse_deps = CustomImagePackage.objects.filter(id__in=ids)
+ for r in reverse_deps:
+ try:
+ if r.id in included_packages:
+ recipe.excludes_set.add(r)
+ else:
+ recipe.appends_set.remove(r)
+ except:
+ pass
+
+ return JsonResponse({"error": "ok"})
+ except CustomImageRecipe.DoesNotExist:
+ return error_response("Tried to remove package that wasn't"
+ " present")
+
+
+class XhrProject(View):
+ """ Create, delete or edit a project
+
+ Entry point: /xhr_project/<project_id>
+ """
+ def post(self, request, *args, **kwargs):
+ """
+ Edit project control
+
+ Args:
+ layerAdd = layer_version_id layer_version_id ...
+ layerDel = layer_version_id layer_version_id ...
+ projectName = new_project_name
+ machineName = new_machine_name
+
+ Returns:
+ {"error": "ok"}
+ or
+ {"error": <error message>}
+ """
+ try:
+ prj = Project.objects.get(pk=kwargs['project_id'])
+ except Project.DoesNotExist:
+ return error_response("No such project")
+
+ # Add layers
+ if 'layerAdd' in request.POST and len(request.POST['layerAdd']) > 0:
+ for layer_version_id in request.POST['layerAdd'].split(','):
+ try:
+ lv = Layer_Version.objects.get(pk=int(layer_version_id))
+ ProjectLayer.objects.get_or_create(project=prj,
+ layercommit=lv)
+ except Layer_Version.DoesNotExist:
+ return error_response("Layer version %s asked to add "
+ "doesn't exist" % layer_version_id)
+
+ # Remove layers
+ if 'layerDel' in request.POST and len(request.POST['layerDel']) > 0:
+ layer_version_ids = request.POST['layerDel'].split(',')
+ ProjectLayer.objects.filter(
+ project=prj,
+ layercommit_id__in=layer_version_ids).delete()
+
+ # Project name change
+ if 'projectName' in request.POST:
+ prj.name = request.POST['projectName']
+ prj.save()
+
+ # Machine name change
+ if 'machineName' in request.POST:
+ machinevar = prj.projectvariable_set.get(name="MACHINE")
+ machinevar.value = request.POST['machineName']
+ machinevar.save()
+
+ return JsonResponse({"error": "ok"})
+
+ def get(self, request, *args, **kwargs):
+ """
+ Returns:
+ json object representing the current project
+ or:
+ {"error": <error message>}
+ """
+
+ try:
+ project = Project.objects.get(pk=kwargs['project_id'])
+ except Project.DoesNotExist:
+ return error_response("Project %s does not exist" %
+ kwargs['project_id'])
+
+ # Create the frequently built targets list
+
+ freqtargets = Counter(Target.objects.filter(
+ Q(build__project=project),
+ ~Q(build__outcome=Build.IN_PROGRESS)
+ ).order_by("target").values_list("target", flat=True))
+
+ freqtargets = freqtargets.most_common(5)
+
+ # We now have the targets in order of frequency but if there are two
+ # with the same frequency then we need to make sure those are in
+ # alphabetical order without losing the frequency ordering
+
+ tmp = []
+ switch = None
+ for i, freqtartget in enumerate(freqtargets):
+ target, count = freqtartget
+ try:
+ target_next, count_next = freqtargets[i+1]
+ if count == count_next and target > target_next:
+ switch = target
+ continue
+ except IndexError:
+ pass
+
+ tmp.append(target)
+
+ if switch:
+ tmp.append(switch)
+ switch = None
+
+ freqtargets = tmp
+
+ layers = []
+ for layer in project.projectlayer_set.all():
+ layers.append({
+ "id": layer.layercommit.pk,
+ "name": layer.layercommit.layer.name,
+ "vcs_url": layer.layercommit.layer.vcs_url,
+ "local_source_dir": layer.layercommit.layer.local_source_dir,
+ "vcs_reference": layer.layercommit.get_vcs_reference(),
+ "url": layer.layercommit.layer.layer_index_url,
+ "layerdetailurl": layer.layercommit.get_detailspage_url(
+ project.pk),
+ "layersource": layer.layercommit.layer_source
+ })
+
+ data = {
+ "name": project.name,
+ "layers": layers,
+ "freqtargets": freqtargets,
+ }
+
+ if project.release is not None:
+ data['release'] = {
+ "id": project.release.pk,
+ "name": project.release.name,
+ "description": project.release.description
+ }
+
+ try:
+ data["machine"] = {"name":
+ project.projectvariable_set.get(
+ name="MACHINE").value}
+ except ProjectVariable.DoesNotExist:
+ data["machine"] = None
+ try:
+ data["distro"] = project.projectvariable_set.get(
+ name="DISTRO").value
+ except ProjectVariable.DoesNotExist:
+ data["distro"] = "-- not set yet"
+
+ data['error'] = "ok"
+
+ return JsonResponse(data)
+
+ def put(self, request, *args, **kwargs):
+ # TODO create new project api
+ return HttpResponse()
+
+ def delete(self, request, *args, **kwargs):
+ """Delete a project. Cancels any builds in progress"""
+ try:
+ project = Project.objects.get(pk=kwargs['project_id'])
+ # Cancel any builds in progress
+ for br in BuildRequest.objects.filter(
+ project=project,
+ state=BuildRequest.REQ_INPROGRESS):
+ XhrBuildRequest.cancel_build(br)
+
+ project.delete()
+
+ except Project.DoesNotExist:
+ return error_response("Project %s does not exist" %
+ kwargs['project_id'])
+
+ return JsonResponse({
+ "error": "ok",
+ "gotoUrl": reverse("all-projects", args=[])
+ })
+
+
+class XhrBuild(View):
+ """ Delete a build object
+
+ Entry point: /xhr_build/<build_id>
+ """
+ def delete(self, request, *args, **kwargs):
+ """
+ Delete build data
+
+ Args:
+ build_id = build_id
+
+ Returns:
+ {"error": "ok"}
+ or
+ {"error": <error message>}
+ """
+ try:
+ build = Build.objects.get(pk=kwargs['build_id'])
+ project = build.project
+ build.delete()
+ except Build.DoesNotExist:
+ return error_response("Build %s does not exist" %
+ kwargs['build_id'])
+ return JsonResponse({
+ "error": "ok",
+ "gotoUrl": reverse("projectbuilds", args=(project.pk,))
+ })
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/buildtables.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/buildtables.py
new file mode 100644
index 000000000..dd0a6900d
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/buildtables.py
@@ -0,0 +1,606 @@
+#
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from orm.models import Build, Task, Target, Package
+from django.db.models import Q, Sum
+
+import toastergui.tables as tables
+from toastergui.widgets import ToasterTable
+from toastergui.tablefilter import TableFilter
+from toastergui.tablefilter import TableFilterActionToggle
+
+
+class BuildTablesMixin(ToasterTable):
+ def get_context_data(self, **kwargs):
+ # We need to be explicit about which superclass we're calling here
+ # Otherwise the MRO gets in a right mess
+ context = ToasterTable.get_context_data(self, **kwargs)
+ context['build'] = Build.objects.get(pk=kwargs['build_id'])
+ return context
+
+
+class BuiltPackagesTableBase(tables.PackagesTable):
+ """ Table to display all the packages built in a build """
+ def __init__(self, *args, **kwargs):
+ super(BuiltPackagesTableBase, self).__init__(*args, **kwargs)
+ self.title = "Packages built"
+ self.default_orderby = "name"
+
+ def setup_queryset(self, *args, **kwargs):
+ build = Build.objects.get(pk=kwargs['build_id'])
+ self.static_context_extra['build'] = build
+ self.static_context_extra['target_name'] = None
+ self.queryset = build.package_set.all().exclude(recipe=None)
+ self.queryset = self.queryset.order_by(self.default_orderby)
+
+ def setup_columns(self, *args, **kwargs):
+ super(BuiltPackagesTableBase, self).setup_columns(*args, **kwargs)
+
+ def pkg_link_template(val):
+ """ return the template used for the link with the val as the
+ element value i.e. inside the <a></a>"""
+
+ return ('''
+ <a href="
+ {%% url "package_built_detail" extra.build.pk data.pk %%}
+ ">%s</a>
+ ''' % val)
+
+ def recipe_link_template(val):
+ return ('''
+ {%% if data.recipe %%}
+ <a href="
+ {%% url "recipe" extra.build.pk data.recipe.pk %%}
+ ">%(value)s</a>
+ {%% else %%}
+ %(value)s
+ {%% endif %%}
+ ''' % {'value': val})
+
+ add_pkg_link_to = 'name'
+ add_recipe_link_to = 'recipe__name'
+
+ # Add the recipe and pkg build links to the required columns
+ for column in self.columns:
+ # Convert to template field style accessors
+ tmplv = column['field_name'].replace('__', '.')
+ tmplv = "{{data.%s}}" % tmplv
+
+ if column['field_name'] is add_pkg_link_to:
+ # Don't overwrite an existing template
+ if column['static_data_template']:
+ column['static_data_template'] =\
+ pkg_link_template(column['static_data_template'])
+ else:
+ column['static_data_template'] = pkg_link_template(tmplv)
+
+ column['static_data_name'] = column['field_name']
+
+ elif column['field_name'] is add_recipe_link_to:
+ # Don't overwrite an existing template
+ if column['static_data_template']:
+ column['static_data_template'] =\
+ recipe_link_template(column['static_data_template'])
+ else:
+ column['static_data_template'] =\
+ recipe_link_template(tmplv)
+ column['static_data_name'] = column['field_name']
+
+ self.add_column(title="Layer",
+ field_name="recipe__layer_version__layer__name",
+ hidden=True,
+ orderable=True)
+
+ layer_branch_template = '''
+ {%if not data.recipe.layer_version.layer.local_source_dir %}
+ <span class="text-muted">{{data.recipe.layer_version.branch}}</span>
+ {% else %}
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.recipe.layer_version.layer.name}} is not in a Git repository, so there is no branch associated with it"> </span>
+ {% endif %}
+ '''
+
+ self.add_column(title="Layer branch",
+ field_name="recipe__layer_version__branch",
+ hidden=True,
+ static_data_name="recipe__layer_version__branch",
+ static_data_template=layer_branch_template,
+ orderable=True)
+
+ git_rev_template = '''
+ {% if not data.recipe.layer_version.layer.local_source_dir %}
+ {% with vcs_ref=data.recipe.layer_version.commit %}
+ {% include 'snippets/gitrev_popover.html' %}
+ {% endwith %}
+ {% else %}
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.recipe.layer_version.layer.name}} is not in a Git repository, so there is no revision associated with it"> </span>
+ {% endif %}
+ '''
+
+ self.add_column(title="Layer commit",
+ static_data_name='vcs_ref',
+ static_data_template=git_rev_template,
+ hidden=True)
+
+
+class BuiltPackagesTable(BuildTablesMixin, BuiltPackagesTableBase):
+ """ Show all the packages built for the selected build """
+ def __init__(self, *args, **kwargs):
+ super(BuiltPackagesTable, self).__init__(*args, **kwargs)
+ self.title = "Packages built"
+ self.default_orderby = "name"
+
+ self.empty_state =\
+ ('<strong>No packages were built.</strong> How did this happen? '
+ 'Well, BitBake reuses as much stuff as possible. '
+ 'If all of the packages needed were already built and available '
+ 'in your build infrastructure, BitBake '
+ 'will not rebuild any of them. This might be slightly confusing, '
+ 'but it does make everything faster.')
+
+ def setup_columns(self, *args, **kwargs):
+ super(BuiltPackagesTable, self).setup_columns(*args, **kwargs)
+
+ def remove_dep_cols(columns):
+ for column in columns:
+ # We don't need these fields
+ if column['static_data_name'] in ['reverse_dependencies',
+ 'dependencies']:
+ continue
+
+ yield column
+
+ self.columns = list(remove_dep_cols(self.columns))
+
+
+class InstalledPackagesTable(BuildTablesMixin, BuiltPackagesTableBase):
+ """ Show all packages installed in an image """
+ def __init__(self, *args, **kwargs):
+ super(InstalledPackagesTable, self).__init__(*args, **kwargs)
+ self.title = "Packages Included"
+ self.default_orderby = "name"
+
+ def make_package_list(self, target):
+ # The database design means that you get the intermediate objects and
+ # not package objects like you'd really want so we get them here
+ pkgs = target.target_installed_package_set.values_list('package',
+ flat=True)
+ return Package.objects.filter(pk__in=pkgs)
+
+ def get_context_data(self, **kwargs):
+ context = super(InstalledPackagesTable,
+ self).get_context_data(**kwargs)
+
+ target = Target.objects.get(pk=kwargs['target_id'])
+ packages = self.make_package_list(target)
+
+ context['packages_sum'] = packages.aggregate(
+ Sum('installed_size'))['installed_size__sum']
+
+ context['target'] = target
+ return context
+
+ def setup_queryset(self, *args, **kwargs):
+ build = Build.objects.get(pk=kwargs['build_id'])
+ self.static_context_extra['build'] = build
+
+ target = Target.objects.get(pk=kwargs['target_id'])
+ # We send these separately because in the case of image details table
+ # we don't have a target just the recipe name as the target
+ self.static_context_extra['target_name'] = target.target
+ self.static_context_extra['target_id'] = target.pk
+
+ self.static_context_extra['add_links'] = True
+
+ self.queryset = self.make_package_list(target)
+ self.queryset = self.queryset.order_by(self.default_orderby)
+
+ def setup_columns(self, *args, **kwargs):
+ super(InstalledPackagesTable, self).setup_columns(**kwargs)
+ self.add_column(title="Installed size",
+ static_data_name="installed_size",
+ static_data_template="{% load projecttags %}"
+ "{{data.size|filtered_filesizeformat}}",
+ orderable=True,
+ hidden=True)
+
+ # Add the template to show installed name for installed packages
+ install_name_tmpl =\
+ ('<a href="{% url "package_included_detail" extra.build.pk'
+ ' extra.target_id data.pk %}">{{data.name}}</a>'
+ '{% if data.installed_name and data.installed_name !='
+ ' data.name %}'
+ '<span class="text-muted"> as {{data.installed_name}}</span>'
+ ' <span class="glyphicon glyphicon-question-sign get-help hover-help"'
+ ' title="{{data.name}} was renamed at packaging time and'
+ ' was installed in your image as {{data.installed_name}}'
+ '"></span>{% endif %} ')
+
+ for column in self.columns:
+ if column['static_data_name'] == 'name':
+ column['static_data_template'] = install_name_tmpl
+ break
+
+
+class BuiltRecipesTable(BuildTablesMixin):
+ """ Table to show the recipes that have been built in this build """
+
+ def __init__(self, *args, **kwargs):
+ super(BuiltRecipesTable, self).__init__(*args, **kwargs)
+ self.title = "Recipes built"
+ self.default_orderby = "name"
+
+ def setup_queryset(self, *args, **kwargs):
+ build = Build.objects.get(pk=kwargs['build_id'])
+ self.static_context_extra['build'] = build
+ self.queryset = build.get_recipes()
+ self.queryset = self.queryset.order_by(self.default_orderby)
+
+ def setup_columns(self, *args, **kwargs):
+ recipe_name_tmpl =\
+ '<a href="{% url "recipe" extra.build.pk data.pk %}">'\
+ '{{data.name}}'\
+ '</a>'
+
+ recipe_file_tmpl =\
+ '{{data.file_path}}'\
+ '{% if data.pathflags %}<i>({{data.pathflags}})</i>'\
+ '{% endif %}'
+
+ git_branch_template = '''
+ {% if data.layer_version.layer.local_source_dir %}
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.layer_version.layer.name}} is not in a Git repository, so there is no branch associated with it"> </span>
+ {% else %}
+ <span>{{data.layer_version.branch}}</span>
+ {% endif %}
+ '''
+
+ git_rev_template = '''
+ {% if data.layer_version.layer.local_source_dir %}
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.layer_version.layer.name}} is not in a Git repository, so there is no commit associated with it"> </span>
+ {% else %}
+ {% with vcs_ref=data.layer_version.commit %}
+ {% include 'snippets/gitrev_popover.html' %}
+ {% endwith %}
+ {% endif %}
+ '''
+
+ depends_on_tmpl = '''
+ {% with deps=data.r_dependencies_recipe.all %}
+ {% with count=deps|length %}
+ {% if count %}
+ <a class="btn btn-default" title="
+ <a href='{% url "recipe" extra.build.pk data.pk %}#dependencies'>
+ {{data.name}}</a> dependencies"
+ data-content="<ul class='list-unstyled'>
+ {% for dep in deps|dictsort:"depends_on.name"%}
+ <li><a href='{% url "recipe" extra.build.pk dep.depends_on.pk %}'>
+ {{dep.depends_on.name}}</a></li>
+ {% endfor %}
+ </ul>">
+ {{count}}
+ </a>
+ {% endif %}{% endwith %}{% endwith %}
+ '''
+
+ rev_depends_tmpl = '''
+ {% with revs=data.r_dependencies_depends.all %}
+ {% with count=revs|length %}
+ {% if count %}
+ <a class="btn btn-default"
+ title="
+ <a href='{% url "recipe" extra.build.pk data.pk %}#brought-in-by'>
+ {{data.name}}</a> reverse dependencies"
+ data-content="<ul class='list-unstyled'>
+ {% for dep in revs|dictsort:"recipe.name" %}
+ <li>
+ <a href='{% url "recipe" extra.build.pk dep.recipe.pk %}'>
+ {{dep.recipe.name}}
+ </a></li>
+ {% endfor %}
+ </ul>">
+ {{count}}
+ </a>
+ {% endif %}{% endwith %}{% endwith %}
+ '''
+
+ self.add_column(title="Recipe",
+ field_name="name",
+ static_data_name='name',
+ orderable=True,
+ hideable=False,
+ static_data_template=recipe_name_tmpl)
+
+ self.add_column(title="Version",
+ hideable=False,
+ field_name="version")
+
+ self.add_column(title="Dependencies",
+ static_data_name="dependencies",
+ static_data_template=depends_on_tmpl)
+
+ self.add_column(title="Reverse dependencies",
+ static_data_name="revdeps",
+ static_data_template=rev_depends_tmpl,
+ help_text='Recipe build-time reverse dependencies'
+ ' (i.e. the recipes that depend on this recipe)')
+
+ self.add_column(title="Recipe file",
+ field_name="file_path",
+ static_data_name="file_path",
+ static_data_template=recipe_file_tmpl,
+ hidden=True)
+
+ self.add_column(title="Section",
+ field_name="section",
+ orderable=True,
+ hidden=True)
+
+ self.add_column(title="License",
+ field_name="license",
+ help_text='Multiple license names separated by the'
+ ' pipe character indicates a choice between licenses.'
+ ' Multiple license names separated by the ampersand'
+ ' character indicates multiple licenses exist that'
+ ' cover different parts of the source',
+ orderable=True)
+
+ self.add_column(title="Layer",
+ field_name="layer_version__layer__name",
+ orderable=True)
+
+ self.add_column(title="Layer branch",
+ field_name="layer_version__branch",
+ static_data_name="layer_version__branch",
+ static_data_template=git_branch_template,
+ orderable=True,
+ hidden=True)
+
+ self.add_column(title="Layer commit",
+ static_data_name="commit",
+ static_data_template=git_rev_template,
+ hidden=True)
+
+
+class BuildTasksTable(BuildTablesMixin):
+ """ Table to show the tasks that run in this build """
+
+ def __init__(self, *args, **kwargs):
+ super(BuildTasksTable, self).__init__(*args, **kwargs)
+ self.title = "Tasks"
+ self.default_orderby = "order"
+
+ # Toggle these columns on off for Time/CPU usage/Disk I/O tables
+ self.toggle_columns = {}
+
+ def setup_queryset(self, *args, **kwargs):
+ build = Build.objects.get(pk=kwargs['build_id'])
+ self.static_context_extra['build'] = build
+ self.queryset = build.task_build.filter(~Q(order=None))
+ self.queryset = self.queryset.order_by(self.default_orderby)
+
+ def setup_filters(self, *args, **kwargs):
+ # Execution outcome types filter
+ executed_outcome = TableFilter(name="execution_outcome",
+ title="Filter Tasks by 'Executed")
+
+ exec_outcome_action_exec = TableFilterActionToggle(
+ "executed",
+ "Executed Tasks",
+ Q(task_executed=True))
+
+ exec_outcome_action_not_exec = TableFilterActionToggle(
+ "not_executed",
+ "Not Executed Tasks",
+ Q(task_executed=False))
+
+ executed_outcome.add_action(exec_outcome_action_exec)
+ executed_outcome.add_action(exec_outcome_action_not_exec)
+
+ # Task outcome types filter
+ task_outcome = TableFilter(name="task_outcome",
+ title="Filter Task by 'Outcome'")
+
+ for outcome_enum, title in Task.TASK_OUTCOME:
+ if outcome_enum is Task.OUTCOME_NA:
+ continue
+ action = TableFilterActionToggle(
+ title.replace(" ", "_").lower(),
+ "%s Tasks" % title,
+ Q(outcome=outcome_enum))
+
+ task_outcome.add_action(action)
+
+ # SSTATE outcome types filter
+ sstate_outcome = TableFilter(name="sstate_outcome",
+ title="Filter Task by 'Cache attempt'")
+
+ for sstate_result_enum, title in Task.SSTATE_RESULT:
+ action = TableFilterActionToggle(
+ title.replace(" ", "_").lower(),
+ "Tasks with '%s' attempts" % title,
+ Q(sstate_result=sstate_result_enum))
+
+ sstate_outcome.add_action(action)
+
+ self.add_filter(sstate_outcome)
+ self.add_filter(executed_outcome)
+ self.add_filter(task_outcome)
+
+ def setup_columns(self, *args, **kwargs):
+ self.toggle_columns['order'] = len(self.columns)
+
+ recipe_name_tmpl =\
+ '<a href="{% url "recipe" extra.build.pk data.recipe.pk %}">'\
+ '{{data.recipe.name}}'\
+ '</a>'
+
+ def task_link_tmpl(val):
+ return ('<a name="task-{{data.order}}"'
+ 'href="{%% url "task" extra.build.pk data.pk %%}">'
+ '%s'
+ '</a>') % str(val)
+
+ self.add_column(title="Order",
+ static_data_name="order",
+ static_data_template='{{data.order}}',
+ hideable=False,
+ orderable=True)
+
+ self.add_column(title="Task",
+ static_data_name="task_name",
+ static_data_template=task_link_tmpl(
+ "{{data.task_name}}"),
+ hideable=False,
+ orderable=True)
+
+ self.add_column(title="Recipe",
+ static_data_name='recipe__name',
+ static_data_template=recipe_name_tmpl,
+ hideable=False,
+ orderable=True)
+
+ self.add_column(title="Recipe version",
+ field_name='recipe__version',
+ hidden=True)
+
+ self.add_column(title="Executed",
+ static_data_name="task_executed",
+ static_data_template='{{data.get_executed_display}}',
+ filter_name='execution_outcome',
+ orderable=True)
+
+ self.static_context_extra['OUTCOME_FAILED'] = Task.OUTCOME_FAILED
+ outcome_tmpl = '{{data.outcome_text}}'
+ outcome_tmpl = ('%s '
+ '{%% if data.outcome = extra.OUTCOME_FAILED %%}'
+ '<a href="{%% url "build_artifact" extra.build.pk '
+ ' "tasklogfile" data.pk %%}">'
+ ' <span class="glyphicon glyphicon-download-alt'
+ ' get-help" title="Download task log file"></span>'
+ '</a> {%% endif %%}'
+ '<span class="glyphicon glyphicon-question-sign'
+ ' get-help hover-help" style="visibility: hidden;" '
+ 'title="{{data.get_outcome_help}}"></span>'
+ ) % outcome_tmpl
+
+ self.add_column(title="Outcome",
+ static_data_name="outcome",
+ static_data_template=outcome_tmpl,
+ filter_name="task_outcome",
+ orderable=True)
+
+ self.toggle_columns['sstate_result'] = len(self.columns)
+
+ self.add_column(title="Cache attempt",
+ static_data_name="sstate_result",
+ static_data_template='{{data.sstate_text}}',
+ filter_name="sstate_outcome",
+ orderable=True)
+
+ self.toggle_columns['elapsed_time'] = len(self.columns)
+
+ self.add_column(
+ title="Time (secs)",
+ static_data_name="elapsed_time",
+ static_data_template='{% load projecttags %}{% load humanize %}'
+ '{{data.elapsed_time|format_none_and_zero|floatformat:2}}',
+ orderable=True,
+ hidden=True)
+
+ self.toggle_columns['cpu_time_sys'] = len(self.columns)
+
+ self.add_column(
+ title="System CPU time (secs)",
+ static_data_name="cpu_time_system",
+ static_data_template='{% load projecttags %}{% load humanize %}'
+ '{{data.cpu_time_system|format_none_and_zero|floatformat:2}}',
+ hidden=True,
+ orderable=True)
+
+ self.toggle_columns['cpu_time_user'] = len(self.columns)
+
+ self.add_column(
+ title="User CPU time (secs)",
+ static_data_name="cpu_time_user",
+ static_data_template='{% load projecttags %}{% load humanize %}'
+ '{{data.cpu_time_user|format_none_and_zero|floatformat:2}}',
+ hidden=True,
+ orderable=True)
+
+ self.toggle_columns['disk_io'] = len(self.columns)
+
+ self.add_column(
+ title="Disk I/O (ms)",
+ static_data_name="disk_io",
+ static_data_template='{% load projecttags %}{% load humanize %}'
+ '{{data.disk_io|format_none_and_zero|filtered_filesizeformat}}',
+ hidden=True,
+ orderable=True)
+
+
+class BuildTimeTable(BuildTasksTable):
+ """ Same as tasks table but the Time column is default displayed"""
+
+ def __init__(self, *args, **kwargs):
+ super(BuildTimeTable, self).__init__(*args, **kwargs)
+ self.default_orderby = "-elapsed_time"
+
+ def setup_columns(self, *args, **kwargs):
+ super(BuildTimeTable, self).setup_columns(**kwargs)
+
+ self.columns[self.toggle_columns['order']]['hidden'] = True
+ self.columns[self.toggle_columns['sstate_result']]['hidden'] = True
+ self.columns[self.toggle_columns['elapsed_time']]['hidden'] = False
+
+
+class BuildCPUTimeTable(BuildTasksTable):
+ """ Same as tasks table but the CPU usage columns are default displayed"""
+
+ def __init__(self, *args, **kwargs):
+ super(BuildCPUTimeTable, self).__init__(*args, **kwargs)
+ self.default_orderby = "-cpu_time_system"
+
+ def setup_columns(self, *args, **kwargs):
+ super(BuildCPUTimeTable, self).setup_columns(**kwargs)
+
+ self.columns[self.toggle_columns['order']]['hidden'] = True
+ self.columns[self.toggle_columns['sstate_result']]['hidden'] = True
+ self.columns[self.toggle_columns['cpu_time_sys']]['hidden'] = False
+ self.columns[self.toggle_columns['cpu_time_user']]['hidden'] = False
+
+
+class BuildIOTable(BuildTasksTable):
+ """ Same as tasks table but the Disk IO column is default displayed"""
+
+ def __init__(self, *args, **kwargs):
+ super(BuildIOTable, self).__init__(*args, **kwargs)
+ self.default_orderby = "-disk_io"
+
+ def setup_columns(self, *args, **kwargs):
+ super(BuildIOTable, self).setup_columns(**kwargs)
+
+ self.columns[self.toggle_columns['order']]['hidden'] = True
+ self.columns[self.toggle_columns['sstate_result']]['hidden'] = True
+ self.columns[self.toggle_columns['disk_io']]['hidden'] = False
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/fixtures/toastergui-unittest-data.xml b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/fixtures/toastergui-unittest-data.xml
index cf35be4be..4517ed176 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/fixtures/toastergui-unittest-data.xml
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/fixtures/toastergui-unittest-data.xml
@@ -1,5 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0">
+ <object pk="1" model="orm.bitbakeversion">
+ <field type="CharField" name="name">v2.3</field>
+ <field type="GitURLField" name="giturl">git://git.openembedded.org/bitbake</field>
+ <field type="CharField" name="dirpath">b</field>
+ <field type="CharField" name="branch">a</field>
+ </object>
+ <object pk="1" model="orm.release">
+ <field type="CharField" name="name">master</field>
+ <field type="CharField" name="description">master project</field>
+ <field to="orm.bitbake_version" name="bitbake_version">1</field>
+ </object>
<object pk="1" model="orm.project">
<field type="CharField" name="name">a test project</field>
<field type="CharField" name="short_description"></field>
@@ -82,9 +93,8 @@
<field to="orm.build" name="build" rel="ManyToOneRel">1</field>
<field type="CharField" name="target">a image recipe</field>
<field type="CharField" name="task"><None></None></field>
- <field type="BooleanField" name="is_image">False</field>
- <field type="IntegerField" name="image_size">0</field>
- <field type="CharField" name="license_manifest_path"><None></None></field>
+ <field type="BooleanField" name="is_image">True</field>
+ <field type="IntegerField" name="image_size">290</field>
</object>
<object pk="2" model="orm.target">
<field to="orm.build" name="build" rel="ManyToOneRel">2</field>
@@ -118,9 +128,9 @@
</object>
<object pk="2" model="orm.package">
<field to="orm.build" name="build" rel="ManyToOneRel">1</field>
- <field to="orm.recipe" name="recipe" rel="ManyToOneRel">2</field>
+ <field to="orm.recipe" name="recipe" rel="ManyToOneRel">1</field>
<field type="CharField" name="name">f pkg</field>
- <field type="CharField" name="installed_name"></field>
+ <field type="CharField" name="installed_name">f</field>
<field type="CharField" name="version"></field>
<field type="CharField" name="revision"></field>
<field type="TextField" name="summary"></field>
@@ -196,8 +206,6 @@
<field to="orm.customimagerecipe" name="recipe_appends" rel="ManyToManyRel"><object pk="3"></object></field>
</object>
<object pk="1" model="orm.recipe">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field type="CharField" name="name">z recipe</field>
<field type="CharField" name="version">5.2</field>
@@ -213,8 +221,6 @@
<field type="BooleanField" name="is_image">False</field>
</object>
<object pk="2" model="orm.recipe">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field type="CharField" name="name">a recipe</field>
<field type="CharField" name="version">1.2</field>
@@ -230,8 +236,6 @@
<field type="BooleanField" name="is_image">False</field>
</object>
<object pk="3" model="orm.recipe">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel"><None></None></field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field type="CharField" name="name">a custom recipe</field>
<field type="CharField" name="version"></field>
@@ -247,8 +251,6 @@
<field type="BooleanField" name="is_image">False</field>
</object>
<object pk="4" model="orm.recipe">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field type="CharField" name="name">a image recipe</field>
<field type="CharField" name="version">1.2</field>
@@ -264,8 +266,6 @@
<field type="BooleanField" name="is_image">True</field>
</object>
<object pk="5" model="orm.recipe">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field type="CharField" name="name">z image recipe</field>
<field type="CharField" name="version">1.3</field>
@@ -281,8 +281,6 @@
<field type="BooleanField" name="is_image">True</field>
</object>
<object pk="6" model="orm.recipe">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel"><None></None></field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field type="CharField" name="name">z custom recipe</field>
<field type="CharField" name="version"></field>
@@ -297,35 +295,34 @@
<field type="CharField" name="pathflags"></field>
<field type="BooleanField" name="is_image">False</field>
</object>
+ <!-- Added for an additional built recipe -->
+ <object pk="6" model="orm.recipe">
+ <field type="CharField" name="name">g recipe</field>
+ <field type="CharField" name="version">1.2.3</field>
+ <field to="orm.layer_version" name="layer_version" rel="ManyToOneRel">3</field>
+ <field type="CharField" name="license">g license</field>
+ <field type="FilePathField" name="file_path">/g</field>
+ <field type="BooleanField" name="is_image">False</field>
+ </object>
+
<object pk="1" model="orm.machine">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel"><None></None></field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field to="orm.layer_version" name="layer_version" rel="ManyToOneRel">1</field>
<field type="CharField" name="name">a machine</field>
<field type="CharField" name="description">a machine</field>
</object>
<object pk="2" model="orm.machine">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel"><None></None></field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field to="orm.layer_version" name="layer_version" rel="ManyToOneRel">2</field>
<field type="CharField" name="name">z machine</field>
<field type="CharField" name="description">z machine</field>
</object>
<object pk="3" model="orm.machine">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel"><None></None></field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field to="orm.layer_version" name="layer_version" rel="ManyToOneRel">1</field>
<field type="CharField" name="name">g machine</field>
<field type="CharField" name="description">g machine</field>
</object>
- <object pk="1" model="orm.layersource">
- <field type="CharField" name="name">local</field>
- <field type="IntegerField" name="sourcetype">1</field>
- <field type="CharField" name="apiurl"></field>
- </object>
<object pk="1" model="orm.bitbakeversion">
<field type="CharField" name="name">test bbv</field>
<field type="CharField" name="giturl">/tmp/</field>
@@ -346,53 +343,24 @@
<field type="CharField" name="branch_name">master</field>
<field type="TextField" name="helptext"><None></None></field>
</object>
- <object pk="1" model="orm.releaselayersourcepriority">
- <field to="orm.release" name="release" rel="ManyToOneRel">1</field>
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="priority">0</field>
- </object>
- <object pk="1" model="orm.branch">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="up_id"><None></None></field>
- <field type="DateTimeField" name="up_date"><None></None></field>
- <field type="CharField" name="name">master</field>
- <field type="CharField" name="short_description"></field>
- </object>
<object pk="1" model="orm.layer">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel"><None></None></field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field type="CharField" name="name">a layer</field>
- <field type="CharField" name="layer_index_url"></field>
<field type="CharField" name="vcs_url">/tmp/</field>
- <field type="CharField" name="vcs_web_url"><None></None></field>
- <field type="CharField" name="vcs_web_tree_base_url"><None></None></field>
- <field type="CharField" name="vcs_web_file_base_url"><None></None></field>
- <field type="TextField" name="summary"><None></None></field>
- <field type="TextField" name="description"><None></None></field>
</object>
<object pk="2" model="orm.layer">
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
<field type="CharField" name="name">z layer</field>
<field type="CharField" name="layer_index_url"></field>
<field type="CharField" name="vcs_url">git://two/</field>
- <field type="CharField" name="vcs_web_url"><None></None></field>
- <field type="CharField" name="vcs_web_tree_base_url"><None></None></field>
- <field type="CharField" name="vcs_web_file_base_url"><None></None></field>
- <field type="TextField" name="summary"><None></None></field>
- <field type="TextField" name="description"><None></None></field>
</object>
<object pk="1" model="orm.layer_version">
- <field to="orm.build" name="build" rel="ManyToOneRel"><None></None></field>
+ <field to="orm.build" name="build" rel="ManyToOneRel">1</field>
<field to="orm.layer" name="layer" rel="ManyToOneRel">1</field>
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
- <field to="orm.branch" name="up_branch" rel="ManyToOneRel">1</field>
- <field type="CharField" name="branch"></field>
- <field type="CharField" name="commit">master</field>
+ <field to="orm.release" name="release" rel="ManyToOneRel">1</field>
+ <field type="CharField" name="branch">master</field>
+ <field type="CharField" name="commit">abcdef123</field>
<field type="CharField" name="dirpath">/tmp/</field>
<field type="IntegerField" name="priority">0</field>
<field type="FilePathField" name="local_path">/</field>
@@ -401,12 +369,22 @@
<object pk="2" model="orm.layer_version">
<field to="orm.build" name="build" rel="ManyToOneRel"><None></None></field>
<field to="orm.layer" name="layer" rel="ManyToOneRel">2</field>
- <field to="orm.layersource" name="layer_source" rel="ManyToOneRel">1</field>
- <field type="IntegerField" name="up_id"><None></None></field>
<field type="DateTimeField" name="up_date"><None></None></field>
- <field to="orm.branch" name="up_branch" rel="ManyToOneRel">1</field>
- <field type="CharField" name="branch"></field>
- <field type="CharField" name="commit">master</field>
+ <field to="orm.release" name="release" rel="ManyToOneRel">1</field>
+ <field type="CharField" name="branch">testing-branch</field>
+ <field type="CharField" name="commit">9876fedcba</field>
+ <field type="CharField" name="dirpath"><None></None></field>
+ <field type="IntegerField" name="priority">0</field>
+ <field type="FilePathField" name="local_path">/</field>
+ <field to="orm.project" name="project" rel="ManyToOneRel"><None></None></field>
+ </object>
+ <object pk="3" model="orm.layer_version">
+ <field to="orm.build" name="build" rel="ManyToOneRel">1</field>
+ <field to="orm.layer" name="layer" rel="ManyToOneRel">2</field>
+ <field type="DateTimeField" name="up_date"><None></None></field>
+ <field to="orm.release" name="release" rel="ManyToOneRel">1</field>
+ <field type="CharField" name="branch">testing-branch</field>
+ <field type="CharField" name="commit">9876fedcba</field>
<field type="CharField" name="dirpath"><None></None></field>
<field type="IntegerField" name="priority">0</field>
<field type="FilePathField" name="local_path">/</field>
@@ -443,4 +421,39 @@
<field type="FilePathField" name="pathname"></field>
<field type="IntegerField" name="lineno"><None></None></field>
</object>
+ <!-- Some tasks for build 1 to test build tables -->
+ <object pk="1" model="orm.task">
+ <field to="orm.build" name="build" rel="ManyToOneRel">1</field>
+ <field type="IntegerField" name="order">1</field>
+ <field type="BooleanField" name="task_executed">False</field>
+ <field type="IntegerField" name="outcome">-1</field>
+ <field type="CharField" name="sstate_checksum">abcdef123</field>
+ <field type="FilePathField" name="path_to_sstate_obj">34/wefw.tar</field>
+ <field to="orm.recipe" name="recipe" rel="ManyToOneRel">1</field>
+ <field type="CharField" name="task_name">a_do_compile</field>
+ <field type="DecimalField" name="elapsed_time">100</field>
+ <field type="IntegerField" name="disk_io">10</field>
+ <field type="IntegerField" name="disk_io_read">11</field>
+ <field type="IntegerField" name="disk_io_write">12</field>
+ <field type="DecimalField" name="cpu_time_user">10.1</field>
+ <field type="DecimalField" name="cpu_time_system">10.2</field>
+ <field type="IntegerField" name="sstate_result">3</field>
+ </object>
+ <object pk="2" model="orm.task">
+ <field to="orm.build" name="build" rel="ManyToOneRel">1</field>
+ <field type="IntegerField" name="order">2</field>
+ <field type="BooleanField" name="task_executed">True</field>
+ <field type="IntegerField" name="outcome">2</field>
+ <field type="CharField" name="sstate_checksum">85bccb7802fd5f48</field>
+ <field type="FilePathField" name="path_to_sstate_obj">85/sstarpm.tgz</field>
+ <field to="orm.recipe" name="recipe" rel="ManyToOneRel">2</field>
+ <field type="CharField" name="task_name">z_do_package_write_rpm</field>
+ <field type="DecimalField" name="elapsed_time">245</field>
+ <field type="IntegerField" name="disk_io">12424</field>
+ <field type="IntegerField" name="disk_io_read">23423</field>
+ <field type="IntegerField" name="disk_io_write">83943</field>
+ <field type="DecimalField" name="cpu_time_user">20394.3</field>
+ <field type="DecimalField" name="cpu_time_system">5363.3</field>
+ <field type="IntegerField" name="sstate_result">1</field>
+ </object>
</django-objects>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap-responsive.min.css b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap-responsive.min.css
deleted file mode 100755
index 059786010..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap-responsive.min.css
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * Bootstrap Responsive v2.3.0
- *
- * 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/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.css b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.css
new file mode 100644
index 000000000..42c79d6e4
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.css
@@ -0,0 +1,6760 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+body {
+ margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+[hidden],
+template {
+ display: none;
+}
+a {
+ background-color: transparent;
+}
+a:active,
+a:hover {
+ outline: 0;
+}
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+b,
+strong {
+ font-weight: bold;
+}
+dfn {
+ font-style: italic;
+}
+h1 {
+ margin: .67em 0;
+ font-size: 2em;
+}
+mark {
+ color: #000;
+ background: #ff0;
+}
+small {
+ font-size: 80%;
+}
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+sup {
+ top: -.5em;
+}
+sub {
+ bottom: -.25em;
+}
+img {
+ border: 0;
+}
+svg:not(:root) {
+ overflow: hidden;
+}
+figure {
+ margin: 1em 40px;
+}
+hr {
+ height: 0;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+pre {
+ overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0;
+ font: inherit;
+ color: inherit;
+}
+button {
+ overflow: visible;
+}
+button,
+select {
+ text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+input {
+ line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+fieldset {
+ padding: .35em .625em .75em;
+ margin: 0 2px;
+ border: 1px solid #c0c0c0;
+}
+legend {
+ padding: 0;
+ border: 0;
+}
+textarea {
+ overflow: auto;
+}
+optgroup {
+ font-weight: bold;
+}
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+td,
+th {
+ padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ color: #000 !important;
+ text-shadow: none !important;
+ background: transparent !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ }
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+ pre,
+ blockquote {
+ border: 1px solid #999;
+
+ page-break-inside: avoid;
+ }
+ thead {
+ display: table-header-group;
+ }
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+ img {
+ max-width: 100% !important;
+ }
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+ .navbar {
+ display: none;
+ }
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+ .label {
+ border: 1px solid #000;
+ }
+ .table {
+ border-collapse: collapse !important;
+ }
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+@font-face {
+ font-family: 'Glyphicons Halflings';
+
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.glyphicon-asterisk:before {
+ content: "\002a";
+}
+.glyphicon-plus:before {
+ content: "\002b";
+}
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+.glyphicon-minus:before {
+ content: "\2212";
+}
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+.glyphicon-glass:before {
+ content: "\e001";
+}
+.glyphicon-music:before {
+ content: "\e002";
+}
+.glyphicon-search:before {
+ content: "\e003";
+}
+.glyphicon-heart:before {
+ content: "\e005";
+}
+.glyphicon-star:before {
+ content: "\e006";
+}
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+.glyphicon-user:before {
+ content: "\e008";
+}
+.glyphicon-film:before {
+ content: "\e009";
+}
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+.glyphicon-th:before {
+ content: "\e011";
+}
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+.glyphicon-ok:before {
+ content: "\e013";
+}
+.glyphicon-remove:before {
+ content: "\e014";
+}
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+.glyphicon-off:before {
+ content: "\e017";
+}
+.glyphicon-signal:before {
+ content: "\e018";
+}
+.glyphicon-cog:before {
+ content: "\e019";
+}
+.glyphicon-trash:before {
+ content: "\e020";
+}
+.glyphicon-home:before {
+ content: "\e021";
+}
+.glyphicon-file:before {
+ content: "\e022";
+}
+.glyphicon-time:before {
+ content: "\e023";
+}
+.glyphicon-road:before {
+ content: "\e024";
+}
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+.glyphicon-download:before {
+ content: "\e026";
+}
+.glyphicon-upload:before {
+ content: "\e027";
+}
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+.glyphicon-lock:before {
+ content: "\e033";
+}
+.glyphicon-flag:before {
+ content: "\e034";
+}
+.glyphicon-headphones:before {
+ content: "\e035";
+}
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+.glyphicon-tag:before {
+ content: "\e041";
+}
+.glyphicon-tags:before {
+ content: "\e042";
+}
+.glyphicon-book:before {
+ content: "\e043";
+}
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+.glyphicon-print:before {
+ content: "\e045";
+}
+.glyphicon-camera:before {
+ content: "\e046";
+}
+.glyphicon-font:before {
+ content: "\e047";
+}
+.glyphicon-bold:before {
+ content: "\e048";
+}
+.glyphicon-italic:before {
+ content: "\e049";
+}
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+.glyphicon-list:before {
+ content: "\e056";
+}
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+.glyphicon-picture:before {
+ content: "\e060";
+}
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+.glyphicon-tint:before {
+ content: "\e064";
+}
+.glyphicon-edit:before {
+ content: "\e065";
+}
+.glyphicon-share:before {
+ content: "\e066";
+}
+.glyphicon-check:before {
+ content: "\e067";
+}
+.glyphicon-move:before {
+ content: "\e068";
+}
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+.glyphicon-backward:before {
+ content: "\e071";
+}
+.glyphicon-play:before {
+ content: "\e072";
+}
+.glyphicon-pause:before {
+ content: "\e073";
+}
+.glyphicon-stop:before {
+ content: "\e074";
+}
+.glyphicon-forward:before {
+ content: "\e075";
+}
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+.glyphicon-eject:before {
+ content: "\e078";
+}
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+.glyphicon-gift:before {
+ content: "\e102";
+}
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+.glyphicon-fire:before {
+ content: "\e104";
+}
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+.glyphicon-plane:before {
+ content: "\e108";
+}
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+.glyphicon-random:before {
+ content: "\e110";
+}
+.glyphicon-comment:before {
+ content: "\e111";
+}
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+.glyphicon-bell:before {
+ content: "\e123";
+}
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+.glyphicon-globe:before {
+ content: "\e135";
+}
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+.glyphicon-filter:before {
+ content: "\e138";
+}
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+.glyphicon-link:before {
+ content: "\e144";
+}
+.glyphicon-phone:before {
+ content: "\e145";
+}
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+.glyphicon-usd:before {
+ content: "\e148";
+}
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+.glyphicon-sort:before {
+ content: "\e150";
+}
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+.glyphicon-expand:before {
+ content: "\e158";
+}
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+.glyphicon-flash:before {
+ content: "\e162";
+}
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+.glyphicon-record:before {
+ content: "\e165";
+}
+.glyphicon-save:before {
+ content: "\e166";
+}
+.glyphicon-open:before {
+ content: "\e167";
+}
+.glyphicon-saved:before {
+ content: "\e168";
+}
+.glyphicon-import:before {
+ content: "\e169";
+}
+.glyphicon-export:before {
+ content: "\e170";
+}
+.glyphicon-send:before {
+ content: "\e171";
+}
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+.glyphicon-header:before {
+ content: "\e180";
+}
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+.glyphicon-tower:before {
+ content: "\e184";
+}
+.glyphicon-stats:before {
+ content: "\e185";
+}
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+.glyphicon-cd:before {
+ content: "\e201";
+}
+.glyphicon-save-file:before {
+ content: "\e202";
+}
+.glyphicon-open-file:before {
+ content: "\e203";
+}
+.glyphicon-level-up:before {
+ content: "\e204";
+}
+.glyphicon-copy:before {
+ content: "\e205";
+}
+.glyphicon-paste:before {
+ content: "\e206";
+}
+.glyphicon-alert:before {
+ content: "\e209";
+}
+.glyphicon-equalizer:before {
+ content: "\e210";
+}
+.glyphicon-king:before {
+ content: "\e211";
+}
+.glyphicon-queen:before {
+ content: "\e212";
+}
+.glyphicon-pawn:before {
+ content: "\e213";
+}
+.glyphicon-bishop:before {
+ content: "\e214";
+}
+.glyphicon-knight:before {
+ content: "\e215";
+}
+.glyphicon-baby-formula:before {
+ content: "\e216";
+}
+.glyphicon-tent:before {
+ content: "\26fa";
+}
+.glyphicon-blackboard:before {
+ content: "\e218";
+}
+.glyphicon-bed:before {
+ content: "\e219";
+}
+.glyphicon-apple:before {
+ content: "\f8ff";
+}
+.glyphicon-erase:before {
+ content: "\e221";
+}
+.glyphicon-hourglass:before {
+ content: "\231b";
+}
+.glyphicon-lamp:before {
+ content: "\e223";
+}
+.glyphicon-duplicate:before {
+ content: "\e224";
+}
+.glyphicon-piggy-bank:before {
+ content: "\e225";
+}
+.glyphicon-scissors:before {
+ content: "\e226";
+}
+.glyphicon-bitcoin:before {
+ content: "\e227";
+}
+.glyphicon-btc:before {
+ content: "\e227";
+}
+.glyphicon-xbt:before {
+ content: "\e227";
+}
+.glyphicon-yen:before {
+ content: "\00a5";
+}
+.glyphicon-jpy:before {
+ content: "\00a5";
+}
+.glyphicon-ruble:before {
+ content: "\20bd";
+}
+.glyphicon-rub:before {
+ content: "\20bd";
+}
+.glyphicon-scale:before {
+ content: "\e230";
+}
+.glyphicon-ice-lolly:before {
+ content: "\e231";
+}
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232";
+}
+.glyphicon-education:before {
+ content: "\e233";
+}
+.glyphicon-option-horizontal:before {
+ content: "\e234";
+}
+.glyphicon-option-vertical:before {
+ content: "\e235";
+}
+.glyphicon-menu-hamburger:before {
+ content: "\e236";
+}
+.glyphicon-modal-window:before {
+ content: "\e237";
+}
+.glyphicon-oil:before {
+ content: "\e238";
+}
+.glyphicon-grain:before {
+ content: "\e239";
+}
+.glyphicon-sunglasses:before {
+ content: "\e240";
+}
+.glyphicon-text-size:before {
+ content: "\e241";
+}
+.glyphicon-text-color:before {
+ content: "\e242";
+}
+.glyphicon-text-background:before {
+ content: "\e243";
+}
+.glyphicon-object-align-top:before {
+ content: "\e244";
+}
+.glyphicon-object-align-bottom:before {
+ content: "\e245";
+}
+.glyphicon-object-align-horizontal:before {
+ content: "\e246";
+}
+.glyphicon-object-align-left:before {
+ content: "\e247";
+}
+.glyphicon-object-align-vertical:before {
+ content: "\e248";
+}
+.glyphicon-object-align-right:before {
+ content: "\e249";
+}
+.glyphicon-triangle-right:before {
+ content: "\e250";
+}
+.glyphicon-triangle-left:before {
+ content: "\e251";
+}
+.glyphicon-triangle-bottom:before {
+ content: "\e252";
+}
+.glyphicon-triangle-top:before {
+ content: "\e253";
+}
+.glyphicon-console:before {
+ content: "\e254";
+}
+.glyphicon-superscript:before {
+ content: "\e255";
+}
+.glyphicon-subscript:before {
+ content: "\e256";
+}
+.glyphicon-menu-left:before {
+ content: "\e257";
+}
+.glyphicon-menu-right:before {
+ content: "\e258";
+}
+.glyphicon-menu-down:before {
+ content: "\e259";
+}
+.glyphicon-menu-up:before {
+ content: "\e260";
+}
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+html {
+ font-size: 10px;
+
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff;
+}
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+a {
+ color: #337ab7;
+ text-decoration: none;
+}
+a:hover,
+a:focus {
+ color: #23527c;
+ text-decoration: underline;
+}
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+figure {
+ margin: 0;
+}
+img {
+ vertical-align: middle;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+.img-rounded {
+ border-radius: 6px;
+}
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
+}
+.img-circle {
+ border-radius: 50%;
+}
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eee;
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+[role="button"] {
+ cursor: pointer;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #777;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+h1,
+.h1 {
+ font-size: 36px;
+}
+h2,
+.h2 {
+ font-size: 30px;
+}
+h3,
+.h3 {
+ font-size: 24px;
+}
+h4,
+.h4 {
+ font-size: 18px;
+}
+h5,
+.h5 {
+ font-size: 14px;
+}
+h6,
+.h6 {
+ font-size: 12px;
+}
+p {
+ margin: 0 0 10px;
+}
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px;
+ }
+}
+small,
+.small {
+ font-size: 85%;
+}
+mark,
+.mark {
+ padding: .2em;
+ background-color: #fcf8e3;
+}
+.text-left {
+ text-align: left;
+}
+.text-right {
+ text-align: right;
+}
+.text-center {
+ text-align: center;
+}
+.text-justify {
+ text-align: justify;
+}
+.text-nowrap {
+ white-space: nowrap;
+}
+.text-lowercase {
+ text-transform: lowercase;
+}
+.text-uppercase {
+ text-transform: uppercase;
+}
+.text-capitalize {
+ text-transform: capitalize;
+}
+.text-muted {
+ color: #777;
+}
+.text-primary {
+ color: #337ab7;
+}
+a.text-primary:hover,
+a.text-primary:focus {
+ color: #286090;
+}
+.text-success {
+ color: #3c763d;
+}
+a.text-success:hover,
+a.text-success:focus {
+ color: #2b542c;
+}
+.text-info {
+ color: #31708f;
+}
+a.text-info:hover,
+a.text-info:focus {
+ color: #245269;
+}
+.text-warning {
+ color: #8a6d3b;
+}
+a.text-warning:hover,
+a.text-warning:focus {
+ color: #66512c;
+}
+.text-danger {
+ color: #a94442;
+}
+a.text-danger:hover,
+a.text-danger:focus {
+ color: #843534;
+}
+.bg-primary {
+ color: #fff;
+ background-color: #337ab7;
+}
+a.bg-primary:hover,
+a.bg-primary:focus {
+ background-color: #286090;
+}
+.bg-success {
+ background-color: #dff0d8;
+}
+a.bg-success:hover,
+a.bg-success:focus {
+ background-color: #c1e2b3;
+}
+.bg-info {
+ background-color: #d9edf7;
+}
+a.bg-info:hover,
+a.bg-info:focus {
+ background-color: #afd9ee;
+}
+.bg-warning {
+ background-color: #fcf8e3;
+}
+a.bg-warning:hover,
+a.bg-warning:focus {
+ background-color: #f7ecb5;
+}
+.bg-danger {
+ background-color: #f2dede;
+}
+a.bg-danger:hover,
+a.bg-danger:focus {
+ background-color: #e4b9b9;
+}
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eee;
+}
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+.list-inline {
+ padding-left: 0;
+ margin-left: -5px;
+ list-style: none;
+}
+.list-inline > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px;
+}
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+dt,
+dd {
+ line-height: 1.42857143;
+}
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #777;
+}
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eee;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid #eee;
+ border-left: 0;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
+}
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #fff;
+ background-color: #333;
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+}
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+.container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
+}
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
+}
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
+}
+.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+.row {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+.col-xs-12 {
+ width: 100%;
+}
+.col-xs-11 {
+ width: 91.66666667%;
+}
+.col-xs-10 {
+ width: 83.33333333%;
+}
+.col-xs-9 {
+ width: 75%;
+}
+.col-xs-8 {
+ width: 66.66666667%;
+}
+.col-xs-7 {
+ width: 58.33333333%;
+}
+.col-xs-6 {
+ width: 50%;
+}
+.col-xs-5 {
+ width: 41.66666667%;
+}
+.col-xs-4 {
+ width: 33.33333333%;
+}
+.col-xs-3 {
+ width: 25%;
+}
+.col-xs-2 {
+ width: 16.66666667%;
+}
+.col-xs-1 {
+ width: 8.33333333%;
+}
+.col-xs-pull-12 {
+ right: 100%;
+}
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+.col-xs-pull-9 {
+ right: 75%;
+}
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+.col-xs-pull-6 {
+ right: 50%;
+}
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+.col-xs-pull-3 {
+ right: 25%;
+}
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+.col-xs-pull-0 {
+ right: auto;
+}
+.col-xs-push-12 {
+ left: 100%;
+}
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+.col-xs-push-9 {
+ left: 75%;
+}
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+.col-xs-push-6 {
+ left: 50%;
+}
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+.col-xs-push-3 {
+ left: 25%;
+}
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+.col-xs-push-0 {
+ left: auto;
+}
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+.col-xs-offset-0 {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+ .col-sm-12 {
+ width: 100%;
+ }
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+ .col-sm-9 {
+ width: 75%;
+ }
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+ .col-sm-6 {
+ width: 50%;
+ }
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+ .col-sm-3 {
+ width: 25%;
+ }
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-sm-pull-0 {
+ right: auto;
+ }
+ .col-sm-push-12 {
+ left: 100%;
+ }
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+ .col-sm-push-9 {
+ left: 75%;
+ }
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+ .col-sm-push-6 {
+ left: 50%;
+ }
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+ .col-sm-push-3 {
+ left: 25%;
+ }
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+ .col-sm-push-0 {
+ left: auto;
+ }
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-sm-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+ .col-md-12 {
+ width: 100%;
+ }
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+ .col-md-9 {
+ width: 75%;
+ }
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+ .col-md-6 {
+ width: 50%;
+ }
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+ .col-md-3 {
+ width: 25%;
+ }
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+ .col-md-pull-12 {
+ right: 100%;
+ }
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-md-pull-9 {
+ right: 75%;
+ }
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-md-pull-6 {
+ right: 50%;
+ }
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-md-pull-3 {
+ right: 25%;
+ }
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-md-pull-0 {
+ right: auto;
+ }
+ .col-md-push-12 {
+ left: 100%;
+ }
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+ .col-md-push-9 {
+ left: 75%;
+ }
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+ .col-md-push-6 {
+ left: 50%;
+ }
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+ .col-md-push-3 {
+ left: 25%;
+ }
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+ .col-md-push-0 {
+ left: auto;
+ }
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-md-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+ .col-lg-12 {
+ width: 100%;
+ }
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+ .col-lg-9 {
+ width: 75%;
+ }
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+ .col-lg-6 {
+ width: 50%;
+ }
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+ .col-lg-3 {
+ width: 25%;
+ }
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-lg-pull-0 {
+ right: auto;
+ }
+ .col-lg-push-12 {
+ left: 100%;
+ }
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+ .col-lg-push-9 {
+ left: 75%;
+ }
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+ .col-lg-push-6 {
+ left: 50%;
+ }
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+ .col-lg-push-3 {
+ left: 25%;
+ }
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+ .col-lg-push-0 {
+ left: auto;
+ }
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-lg-offset-0 {
+ margin-left: 0;
+ }
+}
+table {
+ background-color: transparent;
+}
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777;
+ text-align: left;
+}
+th {
+ text-align: left;
+}
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #ddd;
+}
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #ddd;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+.table > tbody + tbody {
+ border-top: 2px solid #ddd;
+}
+.table .table {
+ background-color: #fff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+.table-bordered {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+ position: static;
+ display: table-column;
+ float: none;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ display: table-cell;
+ float: none;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #ebcccc;
+}
+.table-responsive {
+ min-height: .01%;
+ overflow-x: auto;
+}
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #ddd;
+ }
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+input[type="file"] {
+ display: block;
+}
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+select[multiple],
+select[size] {
+ height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+}
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+}
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+ color: #999;
+}
+.form-control::-webkit-input-placeholder {
+ color: #999;
+}
+.form-control::-ms-expand {
+ background-color: transparent;
+ border: 0;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ background-color: #eee;
+ opacity: 1;
+}
+.form-control[disabled],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+}
+textarea.form-control {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-appearance: none;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"].form-control,
+ input[type="time"].form-control,
+ input[type="datetime-local"].form-control,
+ input[type="month"].form-control {
+ line-height: 34px;
+ }
+ input[type="date"].input-sm,
+ input[type="time"].input-sm,
+ input[type="datetime-local"].input-sm,
+ input[type="month"].input-sm,
+ .input-group-sm input[type="date"],
+ .input-group-sm input[type="time"],
+ .input-group-sm input[type="datetime-local"],
+ .input-group-sm input[type="month"] {
+ line-height: 30px;
+ }
+ input[type="date"].input-lg,
+ input[type="time"].input-lg,
+ input[type="datetime-local"].input-lg,
+ input[type="month"].input-lg,
+ .input-group-lg input[type="date"],
+ .input-group-lg input[type="time"],
+ .input-group-lg input[type="datetime-local"],
+ .input-group-lg input[type="month"] {
+ line-height: 46px;
+ }
+}
+.form-group {
+ margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-top: 4px \9;
+ margin-left: -20px;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ vertical-align: middle;
+ cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+.form-control-static {
+ min-height: 34px;
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+}
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
+}
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.form-group-sm select.form-control {
+ height: 30px;
+ line-height: 30px;
+}
+.form-group-sm textarea.form-control,
+.form-group-sm select[multiple].form-control {
+ height: auto;
+}
+.form-group-sm .form-control-static {
+ height: 30px;
+ min-height: 32px;
+ padding: 6px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+select.input-lg {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
+}
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+.form-group-lg select.form-control {
+ height: 46px;
+ line-height: 46px;
+}
+.form-group-lg textarea.form-control,
+.form-group-lg select[multiple].form-control {
+ height: auto;
+}
+.form-group-lg .form-control-static {
+ height: 46px;
+ min-height: 38px;
+ padding: 11px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+.has-feedback {
+ position: relative;
+}
+.has-feedback .form-control {
+ padding-right: 42.5px;
+}
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none;
+}
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback,
+.form-group-lg .form-control + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+}
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback,
+.form-group-sm .form-control + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #3c763d;
+}
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+}
+.has-success .input-group-addon {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #3c763d;
+}
+.has-success .form-control-feedback {
+ color: #3c763d;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #8a6d3b;
+}
+.has-warning .form-control {
+ border-color: #8a6d3b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-warning .form-control:focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+}
+.has-warning .input-group-addon {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #8a6d3b;
+}
+.has-warning .form-control-feedback {
+ color: #8a6d3b;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #a94442;
+}
+.has-error .form-control {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-error .form-control:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+}
+.has-error .input-group-addon {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #a94442;
+}
+.has-error .form-control-feedback {
+ color: #a94442;
+}
+.has-feedback label ~ .form-control-feedback {
+ top: 25px;
+}
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #737373;
+}
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ padding-top: 7px;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
+}
+.form-horizontal .form-group {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
+ }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 11px;
+ font-size: 18px;
+ }
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ font-size: 12px;
+ }
+}
+.btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #333;
+ text-decoration: none;
+}
+.btn:active,
+.btn.active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ opacity: .65;
+}
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default:focus,
+.btn-default.focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+.btn-default:hover {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+ color: #333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus {
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default .badge {
+ color: #fff;
+ background-color: #333;
+}
+.btn-primary {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary:focus,
+.btn-primary.focus {
+ color: #fff;
+ background-color: #286090;
+ border-color: #122b40;
+}
+.btn-primary:hover {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+ color: #fff;
+ background-color: #204d74;
+ border-color: #122b40;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus {
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success:focus,
+.btn-success.focus {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #255625;
+}
+.btn-success:hover {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+ color: #fff;
+ background-color: #398439;
+ border-color: #255625;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff;
+}
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info:focus,
+.btn-info.focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #1b6d85;
+}
+.btn-info:hover {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+ color: #fff;
+ background-color: #269abc;
+ border-color: #1b6d85;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff;
+}
+.btn-warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning:focus,
+.btn-warning.focus {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #985f0d;
+}
+.btn-warning:hover {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+ color: #fff;
+ background-color: #d58512;
+ border-color: #985f0d;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #fff;
+}
+.btn-danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger:focus,
+.btn-danger.focus {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #761c19;
+}
+.btn-danger:hover {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+ color: #fff;
+ background-color: #ac2925;
+ border-color: #761c19;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #fff;
+}
+.btn-link {
+ font-weight: normal;
+ color: #337ab7;
+ border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+ color: #23527c;
+ text-decoration: underline;
+ background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777;
+ text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-block {
+ display: block;
+ width: 100%;
+}
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear;
+}
+.fade.in {
+ opacity: 1;
+}
+.collapse {
+ display: none;
+}
+.collapse.in {
+ display: block;
+}
+tr.collapse.in {
+ display: table-row;
+}
+tbody.collapse.in {
+ display: table-row-group;
+}
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: .35s;
+ -o-transition-duration: .35s;
+ transition-duration: .35s;
+ -webkit-transition-property: height, visibility;
+ -o-transition-property: height, visibility;
+ transition-property: height, visibility;
+}
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-top: 4px solid \9;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+.dropup,
+.dropdown {
+ position: relative;
+}
+.dropdown-toggle:focus {
+ outline: 0;
+}
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ font-size: 14px;
+ text-align: left;
+ list-style: none;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #333;
+ white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ color: #262626;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #fff;
+ text-decoration: none;
+ background-color: #337ab7;
+ outline: 0;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #777;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
+.open > .dropdown-menu {
+ display: block;
+}
+.open > a {
+ outline: 0;
+}
+.dropdown-menu-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu-left {
+ right: auto;
+ left: 0;
+}
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777;
+ white-space: nowrap;
+}
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 990;
+}
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ content: "";
+ border-top: 0;
+ border-bottom: 4px dashed;
+ border-bottom: 4px solid \9;
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+}
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ right: 0;
+ left: auto;
+ }
+ .navbar-right .dropdown-menu-left {
+ right: auto;
+ left: 0;
+ }
+}
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+.btn-toolbar {
+ margin-left: -5px;
+}
+.btn-toolbar .btn,
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group > .btn-group {
+ float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+.btn-group > .btn + .dropdown-toggle {
+ padding-right: 8px;
+ padding-left: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-right: 12px;
+ padding-left: 12px;
+}
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn .caret {
+ margin-left: 0;
+}
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ display: table-cell;
+ float: none;
+ width: 1%;
+}
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+.input-group[class*="col-"] {
+ float: none;
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+.input-group .form-control:focus {
+ z-index: 3;
+}
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1;
+ color: #555;
+ text-align: center;
+ background-color: #eee;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 3px;
+}
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 6px;
+}
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.input-group-addon:first-child {
+ border-right: 0;
+}
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.input-group-addon:last-child {
+ border-left: 0;
+}
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+.input-group-btn > .btn {
+ position: relative;
+}
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ z-index: 2;
+ margin-left: -1px;
+}
+.nav {
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+.nav > li {
+ position: relative;
+ display: block;
+}
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+.nav > li.disabled > a {
+ color: #777;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #777;
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #eee;
+ border-color: #337ab7;
+}
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.nav > li > a > img {
+ max-width: none;
+}
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0;
+}
+.nav-tabs > li > a:hover {
+ border-color: #eee #eee #ddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #555;
+ cursor: default;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+.nav-tabs.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.nav-pills > li {
+ float: left;
+}
+.nav-pills > li > a {
+ border-radius: 4px;
+}
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #fff;
+ background-color: #337ab7;
+}
+.nav-stacked > li {
+ float: none;
+}
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+.nav-justified {
+ width: 100%;
+}
+.nav-justified > li {
+ float: none;
+}
+.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.tab-content > .tab-pane {
+ display: none;
+}
+.tab-content > .active {
+ display: block;
+}
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar {
+ position: relative;
+ min-height: 50px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+}
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 4px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left;
+ }
+}
+.navbar-collapse {
+ padding-right: 15px;
+ padding-left: 15px;
+ overflow-x: visible;
+ -webkit-overflow-scrolling: touch;
+ border-top: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+}
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+@media (min-width: 768px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+.navbar-brand {
+ float: left;
+ height: 50px;
+ padding: 15px 15px;
+ font-size: 18px;
+ line-height: 20px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+.navbar-brand > img {
+ display: block;
+}
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+}
+.navbar-toggle {
+ position: relative;
+ float: right;
+ padding: 9px 10px;
+ margin-top: 8px;
+ margin-right: 15px;
+ margin-bottom: 8px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.navbar-toggle:focus {
+ outline: 0;
+}
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+.navbar-nav {
+ margin: 7.5px -15px;
+}
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px;
+}
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+ .navbar-nav > li {
+ float: left;
+ }
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ }
+}
+.navbar-form {
+ padding: 10px 15px;
+ margin-top: 8px;
+ margin-right: -15px;
+ margin-bottom: 8px;
+ margin-left: -15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+}
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.navbar-btn {
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+.navbar-btn.btn-sm {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.navbar-btn.btn-xs {
+ margin-top: 14px;
+ margin-bottom: 14px;
+}
+.navbar-text {
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important;
+ }
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+.navbar-default {
+ background-color: #f8f8f8;
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-brand {
+ color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #5e5e5e;
+ background-color: transparent;
+}
+.navbar-default .navbar-text {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #333;
+ background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+ border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #ddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #777;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #333;
+ background-color: transparent;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+ }
+}
+.navbar-default .navbar-link {
+ color: #777;
+}
+.navbar-default .navbar-link:hover {
+ color: #333;
+}
+.navbar-default .btn-link {
+ color: #777;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #333;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #ccc;
+}
+.navbar-inverse {
+ background-color: #222;
+ border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+ border-color: #333;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #333;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #fff;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+ }
+}
+.navbar-inverse .navbar-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-link:hover {
+ color: #fff;
+}
+.navbar-inverse .btn-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444;
+}
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+}
+.breadcrumb > li {
+ display: inline-block;
+}
+.breadcrumb > li + li:before {
+ padding: 0 5px;
+ color: #ccc;
+ content: "/\00a0";
+}
+.breadcrumb > .active {
+ color: #777;
+}
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 4px;
+}
+.pagination > li {
+ display: inline;
+}
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ margin-left: -1px;
+ line-height: 1.42857143;
+ color: #337ab7;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ z-index: 2;
+ color: #23527c;
+ background-color: #eee;
+ border-color: #ddd;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 3;
+ color: #fff;
+ cursor: default;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+ border-color: #ddd;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+}
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ text-align: center;
+ list-style: none;
+}
+.pager li {
+ display: inline;
+}
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 15px;
+}
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+}
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+a.label:hover,
+a.label:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.label:empty {
+ display: none;
+}
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+.label-default {
+ background-color: #777;
+}
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #5e5e5e;
+}
+.label-primary {
+ background-color: #337ab7;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #286090;
+}
+.label-success {
+ background-color: #5cb85c;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+.label-info {
+ background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+.label-warning {
+ background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+.label-danger {
+ background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: #777;
+ border-radius: 10px;
+}
+.badge:empty {
+ display: none;
+}
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+.btn-xs .badge,
+.btn-group-xs > .btn .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+a.badge:hover,
+a.badge:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.list-group-item > .badge {
+ float: right;
+}
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+.jumbotron {
+ padding-top: 30px;
+ padding-bottom: 30px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eee;
+}
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
+.container .jumbotron,
+.container-fluid .jumbotron {
+ padding-right: 15px;
+ padding-left: 15px;
+ border-radius: 6px;
+}
+.jumbotron .container {
+ max-width: 100%;
+}
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding-top: 48px;
+ padding-bottom: 48px;
+ }
+ .container .jumbotron,
+ .container-fluid .jumbotron {
+ padding-right: 60px;
+ padding-left: 60px;
+ }
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 63px;
+ }
+}
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: border .2s ease-in-out;
+ -o-transition: border .2s ease-in-out;
+ transition: border .2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+ margin-right: auto;
+ margin-left: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #337ab7;
+}
+.thumbnail .caption {
+ padding: 9px;
+ color: #333;
+}
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+.alert .alert-link {
+ font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+.alert > p + p {
+ margin-top: 5px;
+}
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+.alert-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.alert-success hr {
+ border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+ color: #2b542c;
+}
+.alert-info {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.alert-info hr {
+ border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+ color: #245269;
+}
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.alert-warning hr {
+ border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+ color: #66512c;
+}
+.alert-danger {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.alert-danger hr {
+ border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+ color: #843534;
+}
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+.progress-bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #fff;
+ text-align: center;
+ background-color: #337ab7;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease;
+}
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.media {
+ margin-top: 15px;
+}
+.media:first-child {
+ margin-top: 0;
+}
+.media,
+.media-body {
+ overflow: hidden;
+ zoom: 1;
+}
+.media-body {
+ width: 10000px;
+}
+.media-object {
+ display: block;
+}
+.media-object.img-thumbnail {
+ max-width: none;
+}
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+.media-middle {
+ vertical-align: middle;
+}
+.media-bottom {
+ vertical-align: bottom;
+}
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+.list-group {
+ padding-left: 0;
+ margin-bottom: 20px;
+}
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.list-group-item:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+a.list-group-item,
+button.list-group-item {
+ color: #555;
+}
+a.list-group-item .list-group-item-heading,
+button.list-group-item .list-group-item-heading {
+ color: #333;
+}
+a.list-group-item:hover,
+button.list-group-item:hover,
+a.list-group-item:focus,
+button.list-group-item:focus {
+ color: #555;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+button.list-group-item {
+ width: 100%;
+ text-align: left;
+}
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #eee;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #777;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #c7ddef;
+}
+.list-group-item-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+}
+a.list-group-item-success,
+button.list-group-item-success {
+ color: #3c763d;
+}
+a.list-group-item-success .list-group-item-heading,
+button.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-success:hover,
+button.list-group-item-success:hover,
+a.list-group-item-success:focus,
+button.list-group-item-success:focus {
+ color: #3c763d;
+ background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+button.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+button.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus,
+button.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #3c763d;
+ border-color: #3c763d;
+}
+.list-group-item-info {
+ color: #31708f;
+ background-color: #d9edf7;
+}
+a.list-group-item-info,
+button.list-group-item-info {
+ color: #31708f;
+}
+a.list-group-item-info .list-group-item-heading,
+button.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-info:hover,
+button.list-group-item-info:hover,
+a.list-group-item-info:focus,
+button.list-group-item-info:focus {
+ color: #31708f;
+ background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+button.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+button.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus,
+button.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #31708f;
+ border-color: #31708f;
+}
+.list-group-item-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+}
+a.list-group-item-warning,
+button.list-group-item-warning {
+ color: #8a6d3b;
+}
+a.list-group-item-warning .list-group-item-heading,
+button.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-warning:hover,
+button.list-group-item-warning:hover,
+a.list-group-item-warning:focus,
+button.list-group-item-warning:focus {
+ color: #8a6d3b;
+ background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+button.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+button.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus,
+button.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #8a6d3b;
+ border-color: #8a6d3b;
+}
+.list-group-item-danger {
+ color: #a94442;
+ background-color: #f2dede;
+}
+a.list-group-item-danger,
+button.list-group-item-danger {
+ color: #a94442;
+}
+a.list-group-item-danger .list-group-item-heading,
+button.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-danger:hover,
+button.list-group-item-danger:hover,
+a.list-group-item-danger:focus,
+button.list-group-item-danger:focus {
+ color: #a94442;
+ background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+button.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+button.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus,
+button.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #a94442;
+ border-color: #a94442;
+}
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+.panel {
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+}
+.panel-body {
+ padding: 15px;
+}
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+.panel-title > a,
+.panel-title > small,
+.panel-title > .small,
+.panel-title > small > a,
+.panel-title > .small > a {
+ color: inherit;
+}
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 3px;
+}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 3px;
+}
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #ddd;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+.panel > .table-responsive {
+ margin-bottom: 0;
+ border: 0;
+}
+.panel-group {
+ margin-bottom: 20px;
+}
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 4px;
+}
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #ddd;
+}
+.panel-group .panel-footer {
+ border-top: 0;
+}
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #ddd;
+}
+.panel-default {
+ border-color: #ddd;
+}
+.panel-default > .panel-heading {
+ color: #333;
+ background-color: #f5f5f5;
+ border-color: #ddd;
+}
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ddd;
+}
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333;
+}
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ddd;
+}
+.panel-primary {
+ border-color: #337ab7;
+}
+.panel-primary > .panel-heading {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #337ab7;
+}
+.panel-primary > .panel-heading .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #337ab7;
+}
+.panel-success {
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #d6e9c6;
+}
+.panel-success > .panel-heading .badge {
+ color: #dff0d8;
+ background-color: #3c763d;
+}
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #d6e9c6;
+}
+.panel-info {
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #bce8f1;
+}
+.panel-info > .panel-heading .badge {
+ color: #d9edf7;
+ background-color: #31708f;
+}
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #bce8f1;
+}
+.panel-warning {
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #faebcc;
+}
+.panel-warning > .panel-heading .badge {
+ color: #fcf8e3;
+ background-color: #8a6d3b;
+}
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #faebcc;
+}
+.panel-danger {
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ebccd1;
+}
+.panel-danger > .panel-heading .badge {
+ color: #f2dede;
+ background-color: #a94442;
+}
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ebccd1;
+}
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+}
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+}
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, .15);
+}
+.well-lg {
+ padding: 24px;
+ border-radius: 6px;
+}
+.well-sm {
+ padding: 9px;
+ border-radius: 3px;
+}
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ filter: alpha(opacity=20);
+ opacity: .2;
+}
+.close:hover,
+.close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+button.close {
+ -webkit-appearance: none;
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+}
+.modal-open {
+ overflow: hidden;
+}
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ display: none;
+ overflow: hidden;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ transition: transform .3s ease-out;
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+}
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ outline: 0;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+}
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000;
+}
+.modal-backdrop.fade {
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+.modal-backdrop.in {
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.modal-header {
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.modal-header .close {
+ margin-top: -2px;
+}
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px;
+}
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ }
+ .modal-sm {
+ width: 300px;
+ }
+}
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ filter: alpha(opacity=0);
+ opacity: 0;
+
+ line-break: auto;
+}
+.tooltip.in {
+ filter: alpha(opacity=90);
+ opacity: .9;
+}
+.tooltip.top {
+ padding: 5px 0;
+ margin-top: -3px;
+}
+.tooltip.right {
+ padding: 0 5px;
+ margin-left: 3px;
+}
+.tooltip.bottom {
+ padding: 5px 0;
+ margin-top: 3px;
+}
+.tooltip.left {
+ padding: 0 5px;
+ margin-left: -3px;
+}
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #fff;
+ text-align: center;
+ background-color: #000;
+ border-radius: 4px;
+}
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-left .tooltip-arrow {
+ right: 5px;
+ bottom: 0;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000;
+}
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000;
+}
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+
+ line-break: auto;
+}
+.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;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 5px 5px 0 0;
+}
+.popover-content {
+ padding: 9px 14px;
+}
+.popover > .arrow,
+.popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.popover > .arrow {
+ border-width: 11px;
+}
+.popover > .arrow:after {
+ content: "";
+ border-width: 10px;
+}
+.popover.top > .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, .25);
+ border-bottom-width: 0;
+}
+.popover.top > .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-color: #fff;
+ border-bottom-width: 0;
+}
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, .25);
+ border-left-width: 0;
+}
+.popover.right > .arrow:after {
+ bottom: -10px;
+ left: 1px;
+ content: " ";
+ border-right-color: #fff;
+ border-left-width: 0;
+}
+.popover.bottom > .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, .25);
+}
+.popover.bottom > .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-width: 0;
+ border-bottom-color: #fff;
+}
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999;
+ border-left-color: rgba(0, 0, 0, .25);
+}
+.popover.left > .arrow:after {
+ right: 1px;
+ bottom: -10px;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: #fff;
+}
+.carousel {
+ position: relative;
+}
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+.carousel-inner > .item {
+ position: relative;
+ display: none;
+ -webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
+ transition: .6s ease-in-out left;
+}
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform .6s ease-in-out;
+ -o-transition: -o-transform .6s ease-in-out;
+ transition: transform .6s ease-in-out;
+
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000px;
+ perspective: 1000px;
+ }
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ left: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ left: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ left: 0;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+.carousel-inner > .active {
+ left: 0;
+}
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+.carousel-inner > .next {
+ left: 100%;
+}
+.carousel-inner > .prev {
+ left: -100%;
+}
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+.carousel-inner > .active.left {
+ left: -100%;
+}
+.carousel-inner > .active.right {
+ left: 100%;
+}
+.carousel-control {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 15%;
+ font-size: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+ background-color: rgba(0, 0, 0, 0);
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control.right {
+ right: 0;
+ left: auto;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control:hover,
+.carousel-control:focus {
+ color: #fff;
+ text-decoration: none;
+ filter: alpha(opacity=90);
+ outline: 0;
+ opacity: .9;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+ margin-top: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ font-family: serif;
+ line-height: 1;
+}
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ padding-left: 0;
+ margin-left: -30%;
+ text-align: center;
+ list-style: none;
+}
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+ border: 1px solid #fff;
+ border-radius: 10px;
+}
+.carousel-indicators .active {
+ width: 12px;
+ height: 12px;
+ margin: 0;
+ background-color: #fff;
+}
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 20px;
+ left: 15%;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+}
+.carousel-caption .btn {
+ text-shadow: none;
+}
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -10px;
+ font-size: 30px;
+ }
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -10px;
+ }
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -10px;
+ }
+ .carousel-caption {
+ right: 20%;
+ left: 20%;
+ padding-bottom: 30px;
+ }
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-header:before,
+.modal-header:after,
+.modal-footer:before,
+.modal-footer:after {
+ display: table;
+ content: " ";
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-header:after,
+.modal-footer:after {
+ clear: both;
+}
+.center-block {
+ display: block;
+ margin-right: auto;
+ margin-left: auto;
+}
+.pull-right {
+ float: right !important;
+}
+.pull-left {
+ float: left !important;
+}
+.hide {
+ display: none !important;
+}
+.show {
+ display: block !important;
+}
+.invisible {
+ visibility: hidden;
+}
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+.hidden {
+ display: none !important;
+}
+.affix {
+ position: fixed;
+}
+@-ms-viewport {
+ width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+ table.visible-xs {
+ display: table !important;
+ }
+ tr.visible-xs {
+ display: table-row !important;
+ }
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+ table.visible-sm {
+ display: table !important;
+ }
+ tr.visible-sm {
+ display: table-row !important;
+ }
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+ table.visible-md {
+ display: table !important;
+ }
+ tr.visible-md {
+ display: table-row !important;
+ }
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+ table.visible-lg {
+ display: table !important;
+ }
+ tr.visible-lg {
+ display: table-row !important;
+ }
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+.visible-print {
+ display: none !important;
+}
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+ table.visible-print {
+ display: table !important;
+ }
+ tr.visible-print {
+ display: table-row !important;
+ }
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+.visible-print-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+.visible-print-inline {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+.visible-print-inline-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.css.map b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.css.map
new file mode 100644
index 000000000..09f8cda78
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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AW,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;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CE,oBAAA;CfwkDH;AezkDC;EACE,oBAAA;Cf2kDH;Ae5kDC;EACE,WAAA;Cf8kDH;Ae/kDC;EACE,oBAAA;CfilDH;AellDC;EACE,mBAAA;CfolDH;AehlDC;EACE,YAAA;CfklDH;AelmDC;EACE,WAAA;CfomDH;AermDC;EACE,mBAAA;CfumDH;AexmDC;EACE,mBAAA;Cf0mDH;Ae3mDC;EACE,UAAA;Cf6mDH;Ae9mDC;EACE,mBAAA;CfgnDH;AejnDC;EACE,mBAAA;CfmnDH;AepnDC;EACE,UAAA;CfsnDH;AevnDC;EACE,mBAAA;CfynDH;Ae1nDC;EACE,mBAAA;Cf4nDH;Ae7nDC;EACE,UAAA;Cf+nDH;AehoDC;EACE,mBAAA;CfkoDH;AenoDC;EACE,kBAAA;CfqoDH;AejoDC;EACE,WAAA;CfmoDH;AernDC;EACE,kBAAA;CfunDH;AexnDC;EACE,0BAAA;Cf0nDH;Ae3nDC;EACE,0BAAA;Cf6nDH;Ae9nDC;EACE,iBAAA;CfgoDH;AejoDC;EACE,0BAAA;CfmoDH;AepoDC;EACE,0BAAA;CfsoDH;AevoDC;EACE,iBAAA;CfyoDH;Ae1oDC;EACE,0BAAA;Cf4oDH;Ae7oDC;EACE,0BAAA;Cf+oDH;AehpDC;EACE,iBAAA;CfkpDH;AenpDC;EACE,0BAAA;CfqpDH;AetpDC;EACE,yBAAA;CfwpDH;AezpDC;EACE,gBAAA;Cf2pDH;Aa3pDD;EElCI;IACE,YAAA;GfgsDH;EezrDD;IACE,YAAA;Gf2rDD;Ee5rDD;IACE,oBAAA;Gf8rDD;Ee/rDD;IACE,oBAAA;GfisDD;EelsDD;IACE,WAAA;GfosDD;EersDD;IACE,oBAAA;GfusDD;EexsDD;IACE,oBAAA;Gf0sDD;Ee3sDD;IACE,WAAA;Gf6sDD;Ee9sDD;IACE,oBAAA;GfgtDD;EejtDD;IACE,oBAAA;GfmtDD;EeptDD;IACE,WAAA;GfstDD;EevtDD;IACE,oBAAA;GfytDD;Ee1tDD;IACE,mBAAA;Gf4tDD;Ee9sDD;IACE,YAAA;GfgtDD;EejtDD;IACE,oBAAA;GfmtDD;EeptDD;IACE,oBAAA;GfstDD;EevtDD;IACE,WAAA;GfytDD;Ee1tDD;IACE,oBAAA;Gf4tDD;Ee7tDD;IACE,oBAAA;Gf+tDD;EehuDD;IACE,WAAA;GfkuDD;EenuDD;IACE,oBAAA;GfquDD;EetuDD;IACE,oBAAA;GfwuDD;EezuDD;IACE,WAAA;Gf2uDD;Ee5uDD;IACE,oBAAA;Gf8uDD;Ee/uDD;IACE,mBAAA;GfivDD;Ee7uDD;IACE,YAAA;Gf+uDD;Ee/vDD;IACE,WAAA;GfiwDD;EelwDD;IACE,mBAAA;GfowDD;EerwDD;IACE,mBAAA;GfuwDD;EexwDD;IACE,UAAA;Gf0wDD;Ee3wDD;IACE,mBAAA;Gf6wDD;Ee9wDD;IACE,mBAAA;GfgxDD;EejxDD;IACE,UAAA;GfmxDD;EepxDD;IACE,mBAAA;GfsxDD;EevxDD;IACE,mBAAA;GfyxDD;Ee1xDD;IACE,UAAA;Gf4xDD;Ee7xDD;IACE,mBAAA;Gf+xDD;EehyDD;IACE,kBAAA;GfkyDD;Ee9xDD;IACE,WAAA;GfgyDD;EelxDD;IACE,kBAAA;GfoxDD;EerxDD;IACE,0BAAA;GfuxDD;EexxDD;IACE,0BAAA;Gf0xDD;Ee3xDD;IACE,iBAAA;Gf6xDD;Ee9xDD;IACE,0BAAA;GfgyDD;EejyDD;IACE,0BAAA;GfmyDD;EepyDD;IACE,iBAAA;GfsyDD;EevyDD;IACE,0BAAA;GfyyDD;Ee1yDD;IACE,0BAAA;Gf4yDD;Ee7yDD;IACE,iBAAA;Gf+yDD;EehzDD;IACE,0BAAA;GfkzDD;EenzDD;IACE,yBAAA;GfqzDD;EetzDD;IACE,gBAAA;GfwzDD;CACF;AahzDD;EE3CI;IACE,YAAA;Gf81DH;Eev1DD;IACE,YAAA;Gfy1DD;Ee11DD;IACE,oBAAA;Gf41DD;Ee71DD;IACE,oBAAA;Gf+1DD;Eeh2DD;IACE,WAAA;Gfk2DD;Een2DD;IACE,oBAAA;Gfq2DD;Eet2DD;IACE,oBAAA;Gfw2DD;Eez2DD;IACE,WAAA;Gf22DD;Ee52DD;IACE,oBAAA;Gf82DD;Ee/2DD;IACE,oBAAA;Gfi3DD;Eel3DD;IACE,WAAA;Gfo3DD;Eer3DD;IACE,oBAAA;Gfu3DD;Eex3DD;IACE,mBAAA;Gf03DD;Ee52DD;IACE,YAAA;Gf82DD;Ee/2DD;IACE,oBAAA;Gfi3DD;Eel3DD;IACE,oBAAA;Gfo3DD;Eer3DD;IACE,WAAA;Gfu3DD;Eex3DD;IACE,oBAAA;Gf03DD;Ee33DD;IACE,oBAAA;Gf63DD;Ee93DD;IACE,WAAA;Gfg4DD;Eej4DD;IACE,oBAAA;Gfm4DD;Eep4DD;IACE,oBAAA;Gfs4DD;Eev4DD;IACE,WAAA;Gfy4DD;Ee14DD;IACE,oBAAA;Gf44DD;Ee74DD;IACE,mBAAA;Gf+4DD;Ee34DD;IACE,YAAA;Gf64DD;Ee75DD;IACE,WAAA;Gf+5DD;Eeh6DD;IACE,mBAAA;Gfk6DD;Een6DD;IACE,mBAAA;Gfq6DD;Eet6DD;IACE,UAAA;Gfw6DD;Eez6DD;IACE,mBAAA;Gf26DD;Ee56DD;IACE,mBAAA;Gf86DD;Ee/6DD;IACE,UAAA;Gfi7DD;Eel7DD;IACE,mBAAA;Gfo7DD;Eer7DD;IACE,mBAAA;Gfu7DD;Eex7DD;IACE,UAAA;Gf07DD;Ee37DD;IACE,mBAAA;Gf67DD;Ee97DD;IACE,kBAAA;Gfg8DD;Ee57DD;IACE,WAAA;Gf87DD;Eeh7DD;IACE,kBAAA;Gfk7DD;Een7DD;IACE,0BAAA;Gfq7DD;Eet7DD;IACE,0BAAA;Gfw7DD;Eez7DD;IACE,iBAAA;Gf27DD;Ee57DD;IACE,0BAAA;Gf87DD;Ee/7DD;IACE,0BAAA;Gfi8DD;Eel8DD;IACE,iBAAA;Gfo8DD;Eer8DD;IACE,0BAAA;Gfu8DD;Eex8DD;IACE,0BAAA;Gf08DD;Ee38DD;IACE,iBAAA;Gf68DD;Ee98DD;IACE,0BAAA;Gfg9DD;Eej9DD;IACE,yBAAA;Gfm9DD;Eep9DD;IACE,gBAAA;Gfs9DD;CACF;Aa38DD;EE9CI;IACE,YAAA;Gf4/DH;Eer/DD;IACE,YAAA;Gfu/DD;Eex/DD;IACE,oBAAA;Gf0/DD;Ee3/DD;IACE,oBAAA;Gf6/DD;Ee9/DD;IACE,WAAA;GfggED;EejgED;IACE,oBAAA;GfmgED;EepgED;IACE,oBAAA;GfsgED;EevgED;IACE,WAAA;GfygED;Ee1gED;IACE,oBAAA;Gf4gED;Ee7gED;IACE,oBAAA;Gf+gED;EehhED;IACE,WAAA;GfkhED;EenhED;IACE,oBAAA;GfqhED;EethED;IACE,mBAAA;GfwhED;Ee1gED;IACE,YAAA;Gf4gED;Ee7gED;IACE,oBAAA;Gf+gED;EehhED;IACE,oBAAA;GfkhED;EenhED;IACE,WAAA;GfqhED;EethED;IACE,oBAAA;GfwhED;EezhED;IACE,oBAAA;Gf2hED;Ee5hED;IACE,WAAA;Gf8hED;Ee/hED;IACE,oBAAA;GfiiED;EeliED;IACE,oBAAA;GfoiED;EeriED;IACE,WAAA;GfuiED;EexiED;IACE,oBAAA;Gf0iED;Ee3iED;IACE,mBAAA;Gf6iED;EeziED;IACE,YAAA;Gf2iED;Ee3jED;IACE,WAAA;Gf6jED;Ee9jED;IACE,mBAAA;GfgkED;EejkED;IACE,mBAAA;GfmkED;EepkED;IACE,UAAA;GfskED;EevkED;IACE,mBAAA;GfykED;Ee1kED;IACE,mBAAA;Gf4kED;Ee7kED;IACE,UAAA;Gf+kED;EehlED;IACE,mBAAA;GfklED;EenlED;IACE,mBAAA;GfqlED;EetlED;IACE,UAAA;GfwlED;EezlED;IACE,mBAAA;Gf2lED;Ee5lED;IACE,kBAAA;Gf8lED;Ee1lED;IACE,WAAA;Gf4lED;Ee9kED;IACE,kBAAA;GfglED;EejlED;IACE,0BAAA;GfmlED;EeplED;IACE,0BAAA;GfslED;EevlED;IACE,iBAAA;GfylED;Ee1lED;IACE,0BAAA;Gf4lED;Ee7lED;IACE,0BAAA;Gf+lED;EehmED;IACE,iBAAA;GfkmED;EenmED;IACE,0BAAA;GfqmED;EetmED;IACE,0BAAA;GfwmED;EezmED;IACE,iBAAA;Gf2mED;Ee5mED;IACE,0BAAA;Gf8mED;Ee/mED;IACE,yBAAA;GfinED;EelnED;IACE,gBAAA;GfonED;CACF;AgBxrED;EACE,8BAAA;ChB0rED;AgBxrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChB0rED;AgBxrED;EACE,iBAAA;ChB0rED;AgBprED;EACE,YA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","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v3.3.6 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n border: 0;\n background-color: transparent;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #fff;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #fff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #ccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #fff;\n border: 1px solid #ddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #fff;\n border-color: #ddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #fff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #fff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n 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);\n 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);\n 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);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n 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);\n 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);\n 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);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n 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);\n 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);\n 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);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n 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);\n 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);\n 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);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n 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);\n 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);\n 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);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #fff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #fff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #fff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #fff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #fff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: floor((@gutter / 2));\n padding-right: ceil((@gutter / 2));\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Unstyle the caret on `<select>`s in IE10+.\n &::-ms-expand {\n border: 0;\n background-color: transparent;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655\n }\n\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848\n//\n// Note that as of 8.3, iOS doesn't support `datetime` or `week`.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n &.form-control {\n line-height: @input-height-base;\n }\n\n &.input-sm,\n .input-group-sm & {\n line-height: @input-height-small;\n }\n\n &.input-lg,\n .input-group-lg & {\n line-height: @input-height-large;\n }\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: @form-group-margin-bottom;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because <label>s don't inherit their parent's `cursor`.\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n &[disabled],\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used directly on <label>s\n.radio-inline,\n.checkbox-inline {\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used on elements with <label> descendants\n.radio,\n.checkbox {\n &.disabled,\n fieldset[disabled] & {\n label {\n cursor: @cursor-disabled;\n }\n }\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n // Size it appropriately next to real form controls\n padding-top: (@padding-base-vertical + 1);\n padding-bottom: (@padding-base-vertical + 1);\n // Remove default margin from `p`\n margin-bottom: 0;\n min-height: (@line-height-computed + @font-size-base);\n\n &.input-lg,\n &.input-sm {\n padding-left: 0;\n padding-right: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// The `.form-group-* form-control` variations are sadly duplicated to avoid the\n// issue documented in https://github.com/twbs/bootstrap/issues/15074.\n\n.input-sm {\n .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n}\n.form-group-sm {\n .form-control {\n height: @input-height-small;\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n border-radius: @input-border-radius-small;\n }\n select.form-control {\n height: @input-height-small;\n line-height: @input-height-small;\n }\n textarea.form-control,\n select[multiple].form-control {\n height: auto;\n }\n .form-control-static {\n height: @input-height-small;\n min-height: (@line-height-computed + @font-size-small);\n padding: (@padding-small-vertical + 1) @padding-small-horizontal;\n font-size: @font-size-small;\n line-height: @line-height-small;\n }\n}\n\n.input-lg {\n .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n}\n.form-group-lg {\n .form-control {\n height: @input-height-large;\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-large;\n border-radius: @input-border-radius-large;\n }\n select.form-control {\n height: @input-height-large;\n line-height: @input-height-large;\n }\n textarea.form-control,\n select[multiple].form-control {\n height: auto;\n }\n .form-control-static {\n height: @input-height-large;\n min-height: (@line-height-computed + @font-size-large);\n padding: (@padding-large-vertical + 1) @padding-large-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-large;\n }\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n // Enable absolute positioning\n position: relative;\n\n // Ensure icons don't overlap text\n .form-control {\n padding-right: (@input-height-base * 1.25);\n }\n}\n// Feedback icon (requires .glyphicon classes)\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2; // Ensure icon is above input groups\n display: block;\n width: @input-height-base;\n height: @input-height-base;\n line-height: @input-height-base;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: @input-height-large;\n height: @input-height-large;\n line-height: @input-height-large;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: @input-height-small;\n height: @input-height-small;\n line-height: @input-height-small;\n}\n\n// Feedback states\n.has-success {\n .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n// Reposition feedback icon if input has visible label above\n.has-feedback label {\n\n & ~ .form-control-feedback {\n top: (@line-height-computed + 5); // Height of the `label` and its margin\n }\n &.sr-only ~ .form-control-feedback {\n top: 0;\n }\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n display: block; // account for any element using help-block\n margin-top: 5px;\n margin-bottom: 10px;\n color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n // Kick in the inline\n @media (min-width: @screen-sm-min) {\n // Inline-block all the things for \"inline\"\n .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // In navbar-form, allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-static {\n display: inline-block;\n }\n\n .input-group {\n display: inline-table;\n vertical-align: middle;\n\n .input-group-addon,\n .input-group-btn,\n .form-control {\n width: auto;\n }\n }\n\n // Input groups need that 100% width though\n .input-group > .form-control {\n width: 100%;\n }\n\n .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .radio,\n .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n\n label {\n padding-left: 0;\n }\n }\n .radio input[type=\"radio\"],\n .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n\n // Re-override the feedback icon.\n .has-feedback .form-control-feedback {\n top: 0;\n }\n }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n // Consistent vertical alignment of radios and checkboxes\n //\n // Labels also get some reset styles, but that is scoped to a media query below.\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n // Account for padding we're adding to ensure the alignment and of help text\n // and other content below items\n .radio,\n .checkbox {\n min-height: (@line-height-computed + (@padding-base-vertical + 1));\n }\n\n // Make form groups behave like rows\n .form-group {\n .make-row();\n }\n\n // Reset spacing and right align labels, but scope to media queries so that\n // labels on narrow viewports stack the same as a default form example.\n @media (min-width: @screen-sm-min) {\n .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n }\n\n // Validation states\n //\n // Reposition the icon because it's now within a grid column and columns have\n // `position: relative;` on them. Also accounts for the grid gutter padding.\n .has-feedback .form-control-feedback {\n right: floor((@grid-gutter-width / 2));\n }\n\n // Form group sizes\n //\n // Quick utility class for applying `.input-lg` and `.input-sm` styles to the\n // inputs and labels within a `.form-group`.\n .form-group-lg {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: (@padding-large-vertical + 1);\n font-size: @font-size-large;\n }\n }\n }\n .form-group-sm {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: (@padding-small-vertical + 1);\n font-size: @font-size-small;\n }\n }\n }\n}\n","// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline,\n &.radio label,\n &.checkbox label,\n &.radio-inline label,\n &.checkbox-inline label {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n // Optional feedback icon\n .form-control-feedback {\n color: @text-color;\n }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n .opacity(.65);\n .box-shadow(none);\n }\n\n a& {\n &.disabled,\n fieldset[disabled] & {\n pointer-events: none; // Future-proof disabling of clicks on `<a>` elements\n }\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 25%);\n }\n &:hover {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n\n &:hover,\n &:focus,\n &.focus {\n color: @color;\n background-color: darken(@background, 17%);\n border-color: darken(@border, 25%);\n }\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus,\n &.focus {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n\n &.in { display: block; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base dashed;\n border-top: @caret-width-base solid ~\"\\9\"; // IE8\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base dashed;\n border-bottom: @caret-width-base solid ~\"\\9\"; // IE8\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn,\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n .border-top-radius(@btn-border-radius-base);\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n .border-top-radius(0);\n .border-bottom-radius(@btn-border-radius-base);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n \n &:focus {\n z-index: 3;\n }\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @input-border-radius;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @input-border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @input-border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n z-index: 2;\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 3;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n\n .btn-xs &,\n .btn-group-xs > .btn & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n\n .list-group-item > & {\n float: right;\n }\n\n .list-group-item > & + & {\n margin-right: 5px;\n }\n\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding-top: @jumbotron-padding;\n padding-bottom: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: @jumbotron-heading-font-size;\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n\n.media-body {\n width: 10000px;\n}\n\n.media-object {\n display: block;\n\n // Fix collapse in webkit from max-width: 100% and display: table-cell.\n &.img-thumbnail {\n max-width: none;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item,\nbutton.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a&,\n button& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a,\n > small,\n > .small,\n > small > a,\n > .small > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n > .panel-heading + .panel-collapse > .list-group {\n .list-group-item:first-child {\n .border-top-radius(0);\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n}\n\n// Modifier class for 16:9 aspect ratio\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n\n// Modifier class for 4:3 aspect ratio\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n &:extend(.clearfix all);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-small;\n\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n",".reset-text() {\n font-family: @font-family-base;\n // We deliberately do NOT reset font-size.\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: @line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n .reset-text();\n font-size: @font-size-base;\n\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n .transition-transform(~'0.6s ease-in-out');\n .backface-visibility(~'hidden');\n .perspective(1000px);\n\n &.next,\n &.active.right {\n .translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n .translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n .translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: (@carousel-control-font-size * 1.5);\n height: (@carousel-control-font-size * 1.5);\n margin-top: (@carousel-control-font-size / -2);\n font-size: (@carousel-control-font-size * 1.5);\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: (@carousel-control-font-size / -2);\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: (@carousel-control-font-size / -2);\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n","// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (has been removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table !important; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"]} \ No newline at end of file
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css
index 2b927f84e..4cf729e43 100755
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css
@@ -1,9 +1,6 @@
/*!
- * Bootstrap v2.3.0
- *
- * 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:200px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:220px}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:400px;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 v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.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;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
+/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css.map b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css.map
new file mode 100644
index 000000000..5f49bb374
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap.min.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["less/normalize.less","less/print.less","bootstrap.css","dist/css/bootstrap.css","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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DG,edkkDH,MAAA,aclkDG,edqkDH,MAAA,acrkDG,edwkDH,MAAA,IcxkDG,ed2kDH,MAAA,ac3kDG,ed8kDH,MAAA,ac9kDG,edilDH,MAAA,IcjlDG,edolDH,MAAA,ac/kDG,edklDH,MAAA,YcjmDG,edomDH,MAAA,KcpmDG,gBdumDH,KAAA,KcvmDG,gBd0mDH,KAAA,ac1mDG,gBd6mDH,KAAA,ac7mDG,edgnDH,KAAA,IchnDG,edmnDH,KAAA,acnnDG,edsnDH,KAAA,actnDG,edynDH,KAAA,IcznDG,ed4nDH,KAAA,ac5nDG,ed+nDH,KAAA,ac/nDG,edkoDH,KAAA,IcloDG,edqoDH,KAAA,achoDG,edmoDH,KAAA,YcpnDG,edunDH,KAAA,KcvnDG,kBd0nDH,YAAA,Kc1nDG,kBd6nDH,YAAA,ac7nDG,kBdgoDH,YAAA,achoDG,iBdmoDH,YAAA,IcnoDG,iBdsoDH,YAAA,actoDG,iBdyoDH,YAAA,aczoDG,iBd4oDH,YAAA,Ic5oDG,iBd+oDH,YAAA,ac/oDG,iBdkpDH,YAAA,aclpDG,iBdqpDH,YAAA,IcrpDG,iBdwpDH,YAAA,acxpDG,iBd2pDH,YAAA,Yc7rDG,iBACE,YAAA,EAOJ,yBACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Ud2rDD,MAAA,Kc3rDC,Wd8rDD,MAAA,Kc9rDC,WdisDD,MAAA,acjsDC,WdosDD,MAAA,acpsDC,UdusDD,MAAA,IcvsDC,Ud0sDD,MAAA,ac1sDC,Ud6sDD,MAAA,ac7sDC,UdgtDD,MAAA,IchtDC,UdmtDD,MAAA,acntDC,UdstDD,MAAA,acttDC,UdytDD,MAAA,IcztDC,Ud4tDD,MAAA,ac7sDC,UdgtDD,MAAA,YchtDC,gBdmtDD,MAAA,KcntDC,gBdstDD,MAAA,acttDC,gBdytDD,MAAA,acztDC,ed4tDD,MAAA,Ic5tDC,ed+tDD,MAAA,ac/tDC,edkuDD,MAAA,acluDC,edquDD,MAAA,IcruDC,edwuDD,MAAA,acxuDC,ed2uDD,MAAA,ac3uDC,ed8uDD,MAAA,Ic9uDC,edivDD,MAAA,ac5uDC,ed+uDD,MAAA,Yc9vDC,ediwDD,MAAA,KcjwDC,gBdowDD,KAAA,KcpwDC,gBduwDD,KAAA,acvwDC,gBd0wDD,KAAA,ac1wDC,ed6wDD,KAAA,Ic7wDC,edgxDD,KAAA,achxDC,edmxDD,KAAA,acnxDC,edsxDD,KAAA,IctxDC,edyxDD,KAAA,aczxDC,ed4xDD,KAAA,ac5xDC,ed+xDD,KAAA,Ic/xDC,edkyDD,KAAA,ac7xDC,edgyDD,KAAA,YcjxDC,edoxDD,KAAA,KcpxDC,kBduxDD,YAAA,KcvxDC,kBd0xDD,YAAA,ac1xDC,kBd6xDD,YAAA,ac7xDC,iBdgyDD,YAAA,IchyDC,iBdmyDD,YAAA,acnyDC,iBdsyDD,YAAA,actyDC,iBdyyDD,YAAA,IczyDC,iBd4yDD,YAAA,ac5yDC,iBd+yDD,YAAA,ac/yDC,iBdkzDD,YAAA,IclzDC,iBdqzDD,YAAA,acrzDC,iBdwzDD,YAAA,YY/yDD,iBE3CE,YAAA,GAQF,yBACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Udy1DD,MAAA,Kcz1DC,Wd41DD,MAAA,Kc51DC,Wd+1DD,MAAA,ac/1DC,Wdk2DD,MAAA,acl2DC,Udq2DD,MAAA,Icr2DC,Udw2DD,MAAA,acx2DC,Ud22DD,MAAA,ac32DC,Ud82DD,MAAA,Ic92DC,Udi3DD,MAAA,acj3DC,Udo3DD,MAAA,acp3DC,Udu3DD,MAAA,Icv3DC,Ud03DD,MAAA,ac32DC,Ud82DD,MAAA,Yc92DC,gBdi3DD,MAAA,Kcj3DC,gBdo3DD,MAAA,acp3DC,gBdu3DD,MAAA,acv3DC,ed03DD,MAAA,Ic13DC,ed63DD,MAAA,ac73DC,edg4DD,MAAA,ach4DC,edm4DD,MAAA,Icn4DC,eds4DD,MAAA,act4DC,edy4DD,MAAA,acz4DC,ed44DD,MAAA,Ic54DC,ed+4DD,MAAA,ac14DC,ed64DD,MAAA,Yc55DC,ed+5DD,MAAA,Kc/5DC,gBdk6DD,KAAA,Kcl6DC,gBdq6DD,KAAA,acr6DC,gBdw6DD,KAAA,acx6DC,ed26DD,KAAA,Ic36DC,ed86DD,KAAA,ac96DC,edi7DD,KAAA,acj7DC,edo7DD,KAAA,Icp7DC,edu7DD,KAAA,acv7DC,ed07DD,KAAA,ac17DC,ed67DD,KAAA,Ic77DC,edg8DD,KAAA,ac37DC,ed87DD,KAAA,Yc/6DC,edk7DD,KAAA,Kcl7DC,kBdq7DD,YAAA,Kcr7DC,kBdw7DD,YAAA,acx7DC,kBd27DD,YAAA,ac37DC,iBd87DD,YAAA,Ic97DC,iBdi8DD,YAAA,acj8DC,iBdo8DD,YAAA,acp8DC,iBdu8DD,YAAA,Icv8DC,iBd08DD,YAAA,ac18DC,iBd68DD,YAAA,ac78DC,iBdg9DD,YAAA,Ich9DC,iBdm9DD,YAAA,acn9DC,iBds9DD,YAAA,YY18DD,iBE9CE,YAAA,GAQF,0BACE,UAAA,WAAA,WAAA,WAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,UAAA,Udu/DD,MAAA,Kcv/DC,Wd0/DD,MAAA,Kc1/DC,Wd6/DD,MAAA,ac7/DC,WdggED,MAAA,achgEC,UdmgED,MAAA,IcngEC,UdsgED,MAAA,actgEC,UdygED,MAAA,aczgEC,Ud4gED,MAAA,Ic5gEC,Ud+gED,MAAA,ac/gEC,UdkhED,MAAA,aclhEC,UdqhED,MAAA,IcrhEC,UdwhED,MAAA,aczgEC,Ud4gED,MAAA,Yc5gEC,gBd+gED,MAAA,Kc/gEC,gBdkhED,MAAA,aclhEC,gBdqhED,MAAA,acrhEC,edwhED,MAAA,IcxhEC,ed2hED,MAAA,ac3hEC,ed8hED,MAAA,ac9hEC,ediiED,MAAA,IcjiEC,edoiED,MAAA,acpiEC,eduiED,MAAA,acviEC,ed0iED,MAAA,Ic1iEC,ed6iED,MAAA,acxiEC,ed2iED,MAAA,Yc1jEC,ed6jED,MAAA,Kc7jEC,gBdgkED,KAAA,KchkEC,gBdmkED,KAAA,acnkEC,gBdskED,KAAA,actkEC,edykED,KAAA,IczkEC,ed4kED,KAAA,ac5kEC,ed+kED,KAAA,ac/kEC,edklED,KAAA,IcllEC,edqlED,KAAA,acrlEC,edwlED,KAAA,acxlEC,ed2lED,KAAA,Ic3lEC,ed8lED,KAAA,aczlEC,ed4lED,KAAA,Yc7kEC,e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pC,cAGA,ejB8DA,wBACQ,OAAA,YJ65FT,OAAA,kBmB56FG,mBAAA,KlBw7FM,WAAY,KkBt7FhB,QAAA,IASN,eC3DE,yBACA,eAAA,KpBo+FD,aoBj+FC,MAAA,KnB6+FA,iBAAkB,KmB3+FhB,aAAA,KpBq+FH,mBoBn+FO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBo+FH,mBoBj+FC,MAAA,KnB6+FA,iBAAkB,QAClB,aAAc,QmBz+FR,oBADJ,oBpBo+FH,mCoBj+FG,MAAA,KnB6+FF,iBAAkB,QAClB,aAAc,QmBz+FN,0BnB++FV,0BAHA,0BmB7+FM,0BnB++FN,0BAHA,0BDFC,yCoB3+FK,yCnB++FN,yCmB1+FE,MAAA,KnBk/FA,iBAAkB,QAClB,aAAc,QmB3+FZ,oBpBm+FH,oBoBn+FG,mCnBg/FF,iBAAkB,KmB5+FV,4BnBi/FV,4BAHA,4BDHC,6BCOD,6BAHA,6BkB99FA,sCClBM,sCnBi/FN,sCmB3+FI,iBAAA,KACA,aAAA,KDcJ,oBC9DE,MAAA,KACA,iBAAA,KpB6hGD,aoB1hGC,MAAA,KnBsiGA,iBAAkB,QmBpiGhB,aAAA,QpB8hGH,mBoB5hGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB6hGH,mBoB1hGC,MAAA,KnBsiGA,iBAAkB,QAClB,aAAc,QmBliGR,oBADJ,oBpB6hGH,mCoB1hGG,MAAA,KnBsiGF,iBAAkB,QAClB,aAAc,QmBliGN,0BnBwiGV,0BAHA,0BmBtiGM,0BnBwiGN,0BAHA,0BDFC,yCoBpiGK,yCnBwiGN,yCmBniGE,MAAA,KnB2iGA,iBAAkB,QAClB,aAAc,QmBpiGZ,oBpB4hGH,oBoB5hGG,mCnByiGF,iBAAkB,KmBriGV,4BnB0iGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBphGA,sCCrBM,sCnB0iGN,sCmBpiGI,iBAAA,QACA,aAAA,QDkBJ,oBClEE,MAAA,QACA,iBAAA,KpBslGD,aoBnlGC,MAAA,KnB+lGA,iBAAkB,QmB7lGhB,aAAA,QpBulGH,mBoBrlGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBslGH,mBoBnlGC,MAAA,KnB+lGA,iBAAkB,QAClB,aAAc,QmB3lGR,oBADJ,oBpBslGH,mCoBnlGG,MAAA,KnB+lGF,iBAAkB,QAClB,aAAc,QmB3lGN,0BnBimGV,0BAHA,0BmB/lGM,0BnBimGN,0BAHA,0BDFC,yCoB7lGK,yCnBimGN,yCmB5lGE,MAAA,KnBomGA,iBAAkB,QAClB,aAAc,QmB7lGZ,oBpBqlGH,oBoBrlGG,mCnBkmGF,iBAAkB,KmB9lGV,4BnBmmGV,4BAHA,4BDHC,6BCOD,6BAHA,6BkBzkGA,sCCzBM,sCnBmmGN,sCmB7lGI,iBAAA,QACA,aAAA,QDsBJ,oBCtEE,MAAA,QACA,iBAAA,KpB+oGD,UoB5oGC,MAAA,KnBwpGA,iBAAkB,QmBtpGhB,aAAA,QpBgpGH,gBoB9oGO,gBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpB+oGH,gBoB5oGC,MAAA,KnBwpGA,iBAAkB,QAClB,aAAc,QmBppGR,iBADJ,iBpB+oGH,gCoB5oGG,MAAA,KnBwpGF,iBAAkB,QAClB,aAAc,QmBppGN,uBnB0pGV,uBAHA,uBmBxpGM,uBnB0pGN,uBAHA,uBDFC,sCoBtpGK,sCnB0pGN,sCmBrpGE,MAAA,KnB6pGA,iBAAkB,QAClB,aAAc,QmBtpGZ,iBpB8oGH,iBoB9oGG,gCnB2pGF,iBAAkB,KmBvpGV,yBnB4pGV,yBAHA,yBDHC,0BCOD,0BAHA,0BkB9nGA,mCC7BM,mCnB4pGN,mCmBtpGI,iBAAA,QACA,aAAA,QD0BJ,iBC1EE,MAAA,QACA,iBAAA,KpBwsGD,aoBrsGC,MAAA,KnBitGA,iBAAkB,QmB/sGhB,aAAA,QpBysGH,mBoBvsGO,mBAEN,MAAA,KACE,iBAAA,QACA,aAAA,QpBwsGH,mBoBrsGC,MAAA,KnBitGA,iBAAkB,QAClB,aAAc,QmB7sGR,oBADJ,oBpBwsGH,mCoBrsGG,MAAA,KnBitGF,iBAAkB,QAClB,aAAc,QmB7sGN,0BnBmtGV,0BAHA,0BmBjtGM,0BnBmtGN,0BAHA,0BDFC,yCoB/sGK,yCnBmtGN,yCmB9sGE,MAAA,KnBstGA,iBAAkB,QAClB,aAAc,QmB/sGZ,oBpBusGH,oBoBvsGG,mCnBotGF,iBAAkB,KmBh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mBAKJ,qBAEE,MAAA,QvBvCA,cACC,QAAA,KAAA,K3By0KF,iBAAA,QkDxxKC,WAAY,IAAI,MAAM,KjDozKtB,2BAA4B,IiDjzK1B,0BAAA,IAHJ,mBAAA,mCAMM,cAAA,ElD2xKL,oCkDtxKG,oDjDkzKF,aAAc,IAAI,EiDhzKZ,cAAA,EvBtEL,4D3Bg2KF,4EkDpxKG,WAAA,EjDgzKF,uBAAwB,IiD9yKlB,wBAAA,IvBtEL,0D3B81KF,0EkD7yKC,cAAe,EvB1Df,2BAAA,IACC,0BAAA,IuB0FH,+EAEI,uBAAA,ElDixKH,wBAAA,EkD7wKC,wDlDgxKD,iBAAA,EC4BD,0BACE,iBAAkB,EiDryKpB,8BlD6wKC,ckD7wKD,gCjD0yKE,cAAe,EiD1yKjB,sCAQM,sBlD2wKL,wCC4BC,cAAe,K0Bx5Kf,aAAA,KuByGF,wDlDwxKC,0BC4BC,uBAAwB,IACxB,wBAAyB,IiDrzK3B,yFAoBQ,yFlD2wKP,2DkD5wKO,2DjDwyKN,uBAAwB,IACxB,wBAAyB,IAK3B,wGiDj0KA,wGjD+zKA,wGDtBC,wGCuBD,0EiDh0KA,0EjD8zKA,0EiDtyKU,0EjD8yKR,uBAAwB,IAK1B,uGiD30KA,uGjDy0KA,uGDtBC,uGCuBD,yEiD10KA,yEjDw0KA,yEiD5yKU,yEvB7HR,wBAAA,IuBiGF,sDlDwzKC,yBC4BC,2BAA4B,IAC5B,0BAA2B,IiD3yKrB,qFA1CR,qFAyCQ,wDlDsxKP,wDC4BC,2BAA4B,IAC5B,0BAA2B,IAG7B,oGDtBC,oGCwBD,oGiDj2KA,oGjD81KA,uEiDhzKU,uEjDkzKV,uEiDh2KA,uEjDs2KE,0BAA2B,IAG7B,mGDtBC,mGCwBD,mGiD32KA,mGjDw2KA,sEiDtzKU,sEjDwzKV,sEiD12KA,sEjDg3KE,2BAA4B,IiDrzK1B,0BlD8xKH,qCkDz1KD,0BAAA,qCA+DI,WAAA,IAAA,MAAA,KA/DJ,kDAAA,kDAmEI,WAAA,EAnEJ,uBAAA,yCjD83KE,OAAQ,EiDpzKA,+CjDwzKV,+CiDl4KA,+CjDo4KA,+CAEA,+CANA,+CDjBC,iECoBD,iEiDn4KA,iEjDq4KA,iEAEA,iEANA,iEAWE,YAAa,EiD9zKL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1MG,QAAS,oB/Dm2MV,c+Dr2MC,c/Ds2MH,QAAA,sB+Dj2MG,yB/Dq2MD,kBACF,QAAA,iB+Dj2MG,yB/Dq2MD,mBACF,QAAA,kBgEn6MC,yBhEu6MC,yBgEt6MD,QAAA,wBACA,+CAAU,YhE26MT,QAAA,gBC4BD,iB+Dr8MU,QAAA,gBhE86MX,c+Dx2MG,QAAS,oB/D42MV,c+D92MC,c/D+2MH,QAAA,sB+D12MG,+C/D82MD,kBACF,QAAA,iB+D12MG,+C/D82MD,mBACF,QAAA,kBgEj8MC,+ChEq8MC,yBgEp8MD,QAAA,wBACA,gDAAU,YhEy8MT,QAAA,gBC4BD,iB+Dn+MU,QAAA,gBhE48MX,c+Dj3MG,QAAS,oB/Dq3MV,c+Dv3MC,c/Dw3MH,QAAA,sB+Dn3MG,gD/Du3MD,kBACF,QAAA,iB+Dn3MG,gD/Du3MD,mBACF,QAAA,kBgE/9MC,gDhEm+MC,yBgEl+MD,QAAA,wBACA,0BAAU,YhEu+MT,QAAA,gBC4BD,iB+DjgNU,QAAA,gBhE0+MX,c+D13MG,QAAS,oB/D83MV,c+Dh4MC,c/Di4MH,QAAA,sB+D53MG,0B/Dg4MD,kBACF,QAAA,iB+D53MG,0B/Dg4MD,mBACF,QAAA,kBgEr/MC,0BhEy/MC,yBACF,QAAA,wBgE1/MC,yBhE8/MC,WACF,QAAA,gBgE//MC,+ChEmgNC,WACF,QAAA,gBgEpgNC,gDhEwgNC,WACF,QAAA,gBAGA,0B+Dn3MC,WA4BE,QAAS,gBC5LX,eAAU,QAAA,eACV,aAAU,ehE4hNT,QAAA,gBC4BD,oB+DtjNU,QAAA,gBhE+hNX,iB+Dj4MG,QAAS,oBAMX,iB/D83MD,iB+Dz2MG,QAAS,sB/D82MZ,qB+Dl4MC,QAAS,e/Dq4MV,a+D/3MC,qBAcE,QAAS,iB/Ds3MZ,sB+Dn4MC,QAAS,e/Ds4MV,a+Dh4MC,sBAOE,QAAS,kB/D83MZ,4B+D/3MC,QAAS,eCpLT,ahEujNC,4BACF,QAAA,wBC6BD,aACE,cACE,QAAS"} \ No newline at end of file
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap3-transition.css b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap3-transition.css
new file mode 100644
index 000000000..9644485ca
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/bootstrap3-transition.css
@@ -0,0 +1,238 @@
+/* Changes to the top bar. Template: base.html */
+
+.navbar .brand {
+ padding: 5px 20px;
+}
+
+.logo {
+ padding-top: 2px !important;
+}
+
+/* Changes to the tables pagination */
+
+.pagination {
+ margin: 0 0 40px 0;
+}
+
+select[class^="pagesize"] {
+ margin-bottom: 0;
+}
+
+/* Project configuration page */
+
+ul.configuration-list {
+ margin-left: 0px;
+}
+
+.configuration-list .checkbox {
+ margin-top: 0;
+}
+
+/* Breadcrumbs */
+
+.breadcrumb {
+ padding: 8px 0;
+}
+
+.breadcrumb > li + li::before {
+ content: none;
+}
+
+.breadcrumb .divider {
+ color: #999;
+ padding: 0 5px;
+}
+
+/* Remove the hovering from the .btn-primary buttons when they are disabled */
+
+.btn-primary.disabled.focus,
+.btn-primary.disabled:focus,
+.btn-primary.disabled:hover,
+.btn-primary.focus[disabled],
+.btn-primary[disabled]:focus,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary.focus,
+fieldset[disabled] .btn-primary:focus,
+fieldset[disabled] .btn-primary:hover {
+ background-color: #04c;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+}
+
+/* Table search input field */
+
+.navbar-search {
+ width: 60%;
+}
+
+.navbar-search .input-append {
+ width: 90%;
+}
+
+.navbar-search .input-append input[type="text"] {
+ width: 80%;
+}
+
+#search {
+ width: 60%;
+}
+
+/* Definition lists */
+
+.dl-horizontal dd {
+ margin-left: 220px;
+}
+
+.dl-horizontal dt {
+ width: 200px;
+}
+
+/* Table controls */
+
+.navbar-inner > .navbar-search .input-append {
+ margin-bottom: 5px;
+}
+
+.navbar-search.input-append {
+ margin-bottom: 20px;
+}
+
+/* Modal dialogs */
+
+.modal-dialog {
+ width: 700px;
+}
+
+.modal-body {
+ overflow-y: scroll;
+ max-height: 350px;
+}
+
+.modal-body ul.list-unstyled {
+ margin-left: 0;
+}
+
+.modal-footer {
+ background-color: #f5f5f5;
+}
+
+.modal-content form {
+ margin-bottom: 0;
+}
+
+.modal-dialog .checkbox label,
+.modal-dialog .radio label {
+ padding-left: 0;
+}
+
+/* Typeahead */
+
+.tt-menu {
+ width: 120%;
+ padding: 10px 8px;
+}
+
+.tt-suggestion {
+ padding: 3px 8px;
+ cursor: pointer;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.tt-suggestion.active,
+.tt-suggestion:hover {
+ background-color: #0081c2;
+ color: white;
+}
+
+/* Build form */
+
+#build-input {
+ width: 20em;
+}
+
+/* Clear filter tooltips in toastertables */
+
+.tooltip .btn-small {
+ margin: 10px;
+}
+
+/* Table cell notifications */
+
+.inline-notification,
+#temp-inline-notify {
+ padding: 10px;
+}
+
+/* Table buttons */
+
+td .btn {
+ white-space: normal;
+}
+
+th.add-del-layers {
+ width: 18%;
+}
+
+th.add_rm_pkg_btn {
+ width: 20%;
+}
+
+/* Edit columsn menu */
+
+.dropdown-menu {
+ min-width: 200px;
+}
+
+/* Popover content */
+
+.popover-content > ul {
+ margin-left: 0;
+}
+
+h3.popover-title {
+ line-height: 20px;
+}
+
+.popover {
+ max-width: 400px;
+}
+
+/* Errors and warnings accordions */
+
+#errors .panel-heading,
+#warnings .panel-heading {
+ background-color: transparent;
+}
+
+a.toggle-errors:hover,
+a.toggle-warnings:hover,
+a.warning:focus {
+ text-decoration: none;
+}
+
+a.toggle-errors:focus,
+a.toggle-warnings:focus {
+ outline: none;
+}
+
+/* Landing page */
+
+.jumbotron p {
+ margin-top: 20px;
+ margin-bottom: 30px;
+}
+
+.jumbotron ul {
+ margin-left: 10px;
+ font-size: 21px;
+ font-weight: 200;
+}
+
+.jumbotron ul > li {
+ line-height: 30px;
+}
+
+.jumbotron .img-thumbnail {
+ padding: 0;
+}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/default.css b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/default.css
index b024d962a..ff24e8c1a 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/default.css
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/css/default.css
@@ -1,298 +1,336 @@
+/* New Toaster custom css file for Bootstrap 3 */
+
+/* Set required top body padding for the fixed top navbard */
+body { padding-top: 50px; }
+
/* Style the Yocto Project logo */
-.logo img { height: 30px; width: auto !important; }
-.logo { padding-top: 4px !important; padding-bottom:0px !important; }
+img.logo { height: 30px; vertical-align: bottom; }
+
+/* Style the Yocto Project logo and the Toaster name in the top navbar */
+.toaster-navbar-brand { float: left; margin: 7px 25px 0 0; }
+.toaster-navbar-brand a.brand { color: #777; height: 50px; padding: 15px 5px 15px 15px; font-size: 20px; line-height: 25px; display: inline; }
+.toaster-navbar-brand > a { text-decoration: none; }
+.toaster-navbar-brand > a.brand:hover { color: #5e5e5e; }
+
+/* Style the debugging information in the top navbar */
+.glyphicon-info-sign { color: #777; font-size: 16px; }
+.glyphicon-info-sign:hover { color: #999; cursor: pointer; }
+
+/* Override the negative right margin for the navbar-right class */
+#new-project-button { margin-right: 0; }
+
+/* Increase popovers width to fit commit SHAs */
+.popover { max-width: 350px; }
+
+/* Set a limit to popover height to handle long dependency lists */
+.popover-content { max-height: 350px; overflow: scroll; }
+
+/* Set a limit to modal dialogs height to handle long variable history */
+[id^="variable-"] .modal-content { max-height: 550px; overflow-y: scroll; }
+
+/* Make sure long values in variable history do not make the modal dialogs
+ * scroll horizontally */
+[id^="variable-"] .modal-content p { word-break: break-all; }
-/* style the version information */
-.brand > a { color: #777; }
-.brand > a:hover { color: #999; text-decoration: none; }
-.icon-info-sign { color: #777; font-size: 16px; margin-left: 5px;}
-.icon-info-sign:hover { color: #999; cursor: pointer; }
+/* Increase bottom margin of definition lists inside popovers for the Toaster version information in the top navbar, and also inside the right hand columns of our details pages */
+.popover-content dd,
+.item-info dd { margin-bottom: 15px; }
-/* Style the breadcrumb */
-.breadcrumb { display: inline-block; background-color: transparent; }
+/* Style the horizontal definition lists */
+.dl-horizontal dt { width: 200px; line-height: 25px; }
+.dl-horizontal dd { margin-left: 220px; line-height: 25px; }
+
+/* Style our build results */
+.build-result .progress { margin-bottom: 0; }
+.alert-link.build-warnings,
+.glyphicon-warning-sign.build-warnings { color: #8a6d3b; }
+.build-result .project-name { margin-top: -10px; margin-bottom: 5px; }
+.rebuild-btn, .cancel-build-btn { cursor: pointer; }
/* Styles for the help information */
.get-help { color: #CCCCCC; }
-.get-help:hover, .icon-plus-sign:hover { color: #999999; cursor: pointer; }
-.get-help-green { color: #468847; }
-.get-help-green:hover { color: #347132; cursor: pointer; }
+.get-help:hover { color: #999999; cursor: pointer; }
+.get-help-green { color: #3c763d; }
+.get-help-green:hover { color: #2b542c; cursor: pointer; }
.get-help-blue { color: #3A87AD; }
.get-help-blue:hover { color: #005580; cursor: pointer; }
-.get-help-yellow { color: #C09853; }
-.get-help-yellow:hover { color: #B38942; cursor: pointer; }
-.get-help-red { color: #B94A48; font-size: 16px; padding-left: 2px; }
-.get-help-red:hover { color: #943A38; cursor: pointer; }
-.build-form>i:first-of-type { margin-left: 5px; }
-.manual { margin: 11px 15px 0 11px;}
+.get-help-red { color: #a94442; }
+.get-help-red:hover { color: #843534; cursor: pointer; }
+
+/* Styles for our table controls */
+.form-control[id^="search-input-"],
+.form-control[id^="new-search-input-"],
+#search{ width: 30em; }
+#search-input-selectpackagestable,
+#search-input-packagestable,
+.form-control[id^="no-results-search-input-"] { width: 20em; }
+#edit-columns-button { margin-right: 30px; }
+.navbar-default[id^="table-chrome-"],
+#variables .navbar-default { background-color: transparent; }
+[id^="table-chrome-collapse-"] .navbar-form { margin-left: -15px; }
+.dropdown-menu.editcol { padding-left: 10px; min-width: 200px; }
+span[class^="remove-search-btn-"] { position: absolute; right: 5px; top: 0; bottom: 0; height: 14px; margin: auto; font-size: 14px; cursor: pointer; color: #777;}
+span[class^="remove-search-btn-"]:hover { color: #333; }
+#no-results-special-selectpackagestable .form-inline { margin-top: 20px; }
+[id^="pagination-"] .pagination,
+[id^="pagination-"] .navbar-form { margin-top: 0; }
+[id^="table-chrome-"] .navbar-form { margin-left: -15px; margin-right: -15px; }
+[id^="table-chrome-"] .detail-page-contols,
+#packages-built .detail-page-controls { padding-left: 0; padding-right: 0; }
+
+/* Override the default font-weight for labels: it's a bit too much */
+label { font-weight: normal; }
+
+/* Firefox workaround for awkward fieldset styling. See http://getbootstrap.com/css/#tables-responsive */
+@-moz-document url-prefix() { fieldset { display: table-cell; } }
+
+/* Table heading sortable / not sortable states */
+thead > tr > th > a { font-weight: normal; }
+thead > tr > th > a.sorted { font-weight: bold; color: #333; }
+
+/* Give some extra space to the 'clear filter' buttons */
+.tooltip .btn { margin: 5px; }
+
+/* In table headings, separate the help bubble from the column heading */
+thead > tr > th > .glyphicon-question-sign { margin-right: 5px; }
+
+/* Style build outcome in tables, download, remove and change icons */
+tbody > tr > td > .glyphicon-ok-circle,
+dd > .glyphicon-ok-circle { color: #3c763d; }
+tbody > tr > td > .glyphicon-minus-sign { color: #a94442; }
+.glyphicon-download-alt,
+.glyphicon-edit { color: #337ab7; }
+.failed_tasks .glyphicon-download-alt { margin-left: 5px; }
+.glyphicon-download-alt:hover,
+.glyphicon-edit:hover { color: #23527c; cursor: pointer; text-decoration: none; }
+.glyphicon-trash { color: #a94442; }
+.btn-danger > .glyphicon-trash,
+.btn-danger > .glyphicon-trash:hover { color: #fff; }
+.glyphicon-trash:hover { color: #843534; cursor: pointer; }
+
+/* Set the font size for icons inside headings, lead paragraphs and definition lists */
+h1 > .glyphicon-edit,
+p.lead .glyphicon { font-size: 16px; }
+h2 > .glyphicon-question-sign,
+h3 > .glyphicon-question-sign,
.heading-help { font-size: 14px; }
-/* Styles for the external link */
-.get-info { color: #0088CC; }
-.get-info:hover { color: #005580; cursor: pointer; text-decoration: none; }
-
-/* Styles for code and pre tags */
-code { background-color: transparent; border: none; color: #333333; }
-dd code, .alert code { white-space: pre-wrap; word-break: break-all; word-wrap: break-word; }
-.alert-warning code, .alert-warning pre { background-color: transparent; border: none; color: #C09853; margin-bottom: 0px; }
-.alert-error code { background-color: transparent; border: none; color: #B94A48; margin-bottom:0px; }
-.alert-error pre { background-color: transparent; border: none; color: #B94A48; word-break: normal; margin-bottom: 0px; }
-.alert-warning pre { word-break: normal; }
-.alert-info a { font-weight: 300; }
-.alert-info code { color: #3A87AD; }
-.tooltip code { background-color: transparent; color: #FFFFFF; font-weight: normal; border: none; font-size: 1em; }
-
-/* Style for definition lists */
-dd ul { list-style-type: none; margin: 0px; }
-dt, dd {line-height: 25px; }
-dd li { line-height: 25px; }
-.item-info dd { line-height: 20px; margin-bottom: 10px; }
-
-/* Style the filter modal dialogs */
-.modal { width: 800px; margin-left: -400px; }
-.modal-footer .btn { float: left; }
-.modal-body { max-height: 300px; }
-
-/* Hover style for the clear search icon */
-.icon-remove-sign:hover { color: #999999; cursor: pointer; }
-
-/* Some extra space before headings when needed */
-.details { margin-top: 30px; }
-.air { margin-top: 30px; }
-
-/* Required classes for the highlight behaviour in tables */
-.highlight { -webkit-animation: target-fade 10s 1; -moz-animation: target-fade 10s 1; animation: target-fade 10s 1; }
-@-webkit-keyframes target-fade { 0% { background-color: #D9EDF7; } 25% { background-color: #D9EDF7; } 100% { background-color: white; } }
-@-moz-keyframes target-fade { 0% { background-color: #D9EDF7; } 25% { background-color: #D9EDF7; } 100% { background-color: white; } }
-@keyframes target-fade { 0% { background-color: #D9EDF7; } 25% { background-color: #D9EDF7; } 100% { background-color: white; } }
-
-/* This makes tooltips work inside modal dialogs */
-.tooltip { z-index: 2000 !important; }
-
-/* Override default Twitter Boostrap styles for anchor tags inside tables */
-td a, td a > code { color: #333333; }
-td code { white-space: normal; }
-td a:hover, td a > code:hover { color: #000000; text-decoration: underline; }
-
-/* Override default Twitter Bootstrap styles for tr.error */
-.table tbody tr.error > td { background-color: transparent; } /* override default Bootstrap behaviour */
-.table-hover tbody tr.error:hover > td { background-color: #F5F5F5;} /* override default Bootstrap behaviour */
-
-/* Right justify Bootstrap table columns for size fields */
-.table .sizecol { text-align: right; }
-
-/* Set error, warning, success and muted styles */
-.error, .red, td.error a, tr.error a { color: #b94a48; }
-a.error:hover, a.error:focus, tr.error a:hover { color: #943A38; text-decoration: underline; }
-.warning, .yellow { color: #c09853;}
-a.warning { background-color: transparent; }
-a.warning:hover, a.warning:focus { color: #B38942; text-decoration: underline; }
-.success, .green { color: #468847;}
-.success:hover { color: #347132; text-decoration: underline; }
-td > .success:hover { text-decoration: underline; }
-.muted a { color:#999999; }
-.muted a:hover { color:#999999; }
-
-/* Sorting functionality styles for table headings */
-.sorted { color: #333333; font-weight: bold; }
-.sorted:hover { color: #000000; text-decoration: underline; }
-th > a, th > span { font-weight: normal; }
-
-/* Force long strings like commit hashes to wrap */
-.iscommit { white-space: pre-wrap; word-break: break-all; word-wrap: break-word;}
-
-/* Make the popovers scrollable if they are too long */
-.popover-content { max-height: 30em; overflow-y: scroll; }
-
-/* Styles for the directory structure table. We'll probably won't use those in production */
-.one { padding-left: 18px !important; }
-.two { padding-left: 36px !important; }
-.three { padding-left: 54px !important; }
-.content-directory a { color: #0088CC; }
-.content-directory a:hover { color: #005580; text-decoration: underline; }
-.symlink { color: #CCCCCC; }
-
-/* Styles for the navbar actions */
-.btn-group + .btn-group { margin-right: 10px; }
-.navbar-inner > .btn-group { margin-top: 6px; }
-[id^="search-input-"], #search { width: 80%; }
-
-/* Styles for the parent item in the left navigation */
-
-.nav > li > a.nav-parent { font-size: 18px; line-height: 25px; }
-
-/* Other styles */
-.dropdown-menu { padding: 10px; }
-select { width: auto; }
-.page-header { color: #5A5A5A; }
-.top-air { margin-top: 40px;}
-.progress { margin-bottom: 0px; }
-.lead .badge { font-size: 18px; font-weight: normal; border-radius: 15px; padding: 9px; }
-.lead ol, .lead ul { padding: 10px 0 0 20px; }
-.lead ol > li, .lead ul > li {
- line-height: 35px;
-}
-.well > .lead, .alert .lead { margin-bottom: 0px; }
+/* Create a class for wells without background colour */
.well-transparent { background-color: transparent; }
-.no-results { margin: 10px 0; }
-.task-name { margin-left: 7px; }
-.icon-hand-right {color: #CCCCCC; }
-.help-inline { margin: 5px; }
-.dashboard-section { background-color: transparent; }
-
-/* styles for landing page - analysis mode */
-.hero-unit { margin: 20px 0 30px; }
-.hero-unit > .close { font-size:40px; }
-.hero-actions { margin-top: 30px; }
-
-/* styles for landing page - build mode */
-.hero-unit p { line-height: 25px; }
-.hero-unit p, .hero-unit .btn-large { margin-top: 15px; }
-.hero-unit ul { margin-top: 20px; }
-.hero-unit li { line-height: 30px; }
-.hero-unit img { background-color: #eee; margin-top: 15px; }
-
-/* make tables Chrome-happy (me, not so much) */
-table { table-layout: fixed; word-wrap: break-word; }
-
-table p { margin-bottom: 0 }
-.table td { vertical-align: middle; }
-
-/* styles for the new build button */
-.new-build .btn-primary { padding: 4px 30px; }
-.new-build .alert { margin-top: 10px; }
-.new-build .alert p { margin-top: 10px; }
-
-/* styles for showing the project name in build mode */
-.project-name { padding-top: 0; }
-.project-name .label { font-weight: normal; margin-bottom: 5px; margin-left: -15px; padding: 5px; }
-.project-name .label > a { color: #fff; font-weight: normal; }
-
-/* styles for showing help icons next to command-line builds */
-.build-result .get-help-green, .build-result .get-help-red, .build-result .get-help-blue { margin-right: 35px; margin-top: 8px; font-size: 16px; }
-
-/* Remove bottom margin for forms inside modal dialogs */
-#dependencies-modal-form { margin-bottom: 0px; }
-
-/* Custom column widths */
-.narrow-col { width: 8%; }
-.medium-col { width: 12%; }
-
-/* Configuration styles */
-.icon-trash { color: #B94A48; font-size: 16px; padding-left: 5px; }
-.icon-trash:hover { color: #943A38; text-decoration: none; cursor: pointer; }
-.icon-pencil, .icon-download-alt, .icon-refresh, .icon-star-empty, .icon-star { font-size: 16px; color: #0088CC; padding-left: 2px; }
-.icon-pencil:hover, .icon-download-alt:hover, .icon-refresh:hover, .icon-star-empty:hover, .icon-star:hover, .icon-tasks:hover { color: #005580; text-decoration: none; cursor: pointer; }
-.icon-share { padding-left: 2px; }
-.alert-success .icon-refresh, .alert-success .icon-tasks { color: #468847; }
-.alert-success .icon-refresh:hover, .alert-success .icon-tasks:hover { color: #347132; }
-.alert-error .icon-refresh, .alert-error .icon-tasks { color: #b94a48; }
-.alert-error .icon-refresh:hover, .alert-error .icon-tasks:hover { color: #943A38; }
-.configuration-list li, .configuration-list label { line-height: 35px; font-size: 21px; font-weight: 200; margin-bottom: 0px;}
-.configuration-list { font-size: 16px; margin-bottom: 1.5em; }
-.configuration-list i { font-size: 16px; }
-/*.configuration-layers { height: 135px; overflow: scroll; }*/
-.counter { font-weight: normal; }
-.well-alert { background-color: #FCF8E3; border: 1px solid #FBEED5; border-radius: 4px; }
-.well-alert > .lead { color: #C09853; padding-bottom: .75em; }
-.configuration-alert { margin-bottom: 0px; padding: 8px 14px; }
-.configuration-alert p { margin-bottom: 0px; }
-.project-form { margin-top: 10px; }
-.add-layers .btn-block + .btn-block, .build .btn-block + .btn-block { margin-top: 0px; }
-input.huge { font-size: 17.5px; padding: 11px; min-width: 60%; }
-.build-form { margin-bottom: 0px; }
-.build-form .input-append { margin-bottom: 0px; }
-.build-form .btn-large { padding: 11px 35px; }
-.build-form p { font-size:17.5px ;margin:12px 0 0 10px;}
-#layer-container form, #target-container form { margin-bottom: 0px; }
-.btn-primary .icon-question-sign, .btn-danger .icon-question-sign { color: #fff; }
-.btn-primary .icon-question-sign:hover, .btn-danger .icon-question-sign:hover { color: #999; }
-a code { color: #0088CC; }
-a code:hover { color: #005580; }
-.localconf { font-size: 17.5px; margin-top: 40px; }
-.localconf code { font-size: 17.5px; }
-#add-layer-dependencies { margin-top: 5px; }
-.link-action { font-size: 17.5px; margin-top: 40px; }
-.link-action code { font-size: 17.5px; }
-.artifact { width: 9em; }
-.control-group { margin-bottom: 0px; }
-#project-details form { margin: 0px; }
-dd form { margin: 10px 0 0 0; }
-dl textarea { resize: vertical; }
-.navbar-fixed-top { z-index: 1; }
-.popover { z-index: 2; }
-.btn-danger .icon-trash { color: #fff; }
-.bbappends { list-style-type: none; margin-left: 0; }
-.bbappends li { line-height: 25px; }
-.configuration-list input[type="checkbox"] { margin-top:13px;margin-right:10px; }
-.alert input[type="checkbox"] { margin-top: 0px; margin-right: 3px; }
-.alert ol { padding: 10px 0px 0px 20px; }
-.alert ol > li { line-height: 35px; }
-.dl-vertical form { margin-top: 10px; }
-.scrolling { border: 1px solid #dddddd; height: 154px; overflow: auto; padding: 8px; width: 27.5%; margin-bottom: 10px; }
-.lead .help-block { font-size: 14px; line-height: 20px; font-weight: normal; }
-.button-place .btn { margin: 0 0 20px 0; }
-.tooltip-inner { max-width: 250px; }
-.new-build { padding: 20px; }
-.new-build li { line-height: 30px; }
-.new-build li .alert { line-height: 20px; width: 200px; white-space: normal; }
-.new-build h6 { margin: 10px 0 0 0; color: #5a5a5a; }
-.new-build h3 { margin: 0; color: #5a5a5a; }
-.new-build form { margin: 5px 0 0; }
-.new-build .input-append { margin-bottom: 0; }
-#build-selected { margin-top: 15px; }
-div.add-deps { margin-top: 15px; }
-.btn.log { margin-left: 20px; }
-
-
-.animate-repeat {
- list-style:none;
- box-sizing:border-box;
-}
-.animate-repeat.ng-move,
-.animate-repeat.ng-enter,
-.animate-repeat.ng-leave {
- -webkit-transition:all linear 0.5s;
- transition:all linear 0.5s;
+/* Create a class for the left navigation headers */
+.nav-header { display: block; font-size: 12px; font-weight: bold; line-height: 20px; color: #999; text-transform: uppercase; margin-top: 20px !important; margin-bottom: 15px; padding-left: 15px; }
+
+/* Increase the tabs padding and margin in the project pages to fit the build form and the main content */
+#project-topbar .nav-tabs > li > a { padding: 15px; }
+#project-topbar { margin-bottom: 20px; }
+
+/* Style the project name change form in the project pages */
+#project-name-change-input { width: 20em; }
+
+/* Style the build form in the project pages */
+#project-topbar .input-lg { width: 18em; }
+#project-topbar form .glyphicon { top: 15px; right: 4px; }
+#build-button { padding: 10px 30px; }
+
+/* Style the form links in the project page (all machines, all layers, etc) */
+.form-link { margin-top: 10px; }
+
+/* Style the most built recipes list in the project page */
+#freq-build-list .checkbox input[type="checkbox"] { position: relative; margin: 0 10px 0 0; vertical-align: middle; }
+#freq-build-list.lead > li { line-height: 25px; }
+#freq-build-list { margin-top: 20px; }
+#freq-build-list label { padding-left: 0; }
+#freq-build-btn { margin-top: 10px; }
+#no-most-built { margin-top: 20px; }
+
+/* Style the layers section in the project page and the layer dependencies in the import layer form */
+#layer-container .form-inline { margin-top: 20px; }
+#layer-add-input { width: 17em; }
+ul.lead { margin-top: 20px; }
+ul.lead > li { line-height: 38px; }
+ul.lead .glyphicon-trash,
+ul.lead .glyphicon-trash { font-size: 16px; margin-left: 7px; }
+#layers-in-project-list .tooltip-inner { max-width: 600px; }
+#no-layers-in-project { margin-top: 20px; }
+#no-layers-in-project ul { margin-top: 10px; }
+
+/* Style the layer information icons in the layer details pages */
+dd .glyphicon-trash,
+dd .glyphicon-edit { margin-left: 5px; }
+
+/* Style the forms and definition lists in the layer details pages */
+#change-repo-form .form-control { width: 17em; }
+#information { margin-bottom: 5em; }
+#information dd > form { margin-bottom: 5px; margin-top: 5px; }
+#edit-layer-source-form fieldset { margin-top: 20px; }
+#directory-info,
+#git-repo-info { margin-top: 20px; }
+#layer-dir-path-in-details { width: 55%; }
+.add-deps .form-control { width: 15em; }
+
+/* Style the forms and definition lists in the BitBake variables page */
+.variable-list { margin-bottom: 20px; }
+dd.variable-list form { margin-top: 10px; }
+#new-dl_dir,
+#filter-image_fstypes,
+#new-image_install,
+#new-sstate_dir,
+#new-imagefs_types { width: 20em; }
+#package_classes-select { width: 10em; }
+.scrolling { border: 1px solid #dddddd; height: 154px; overflow: auto; padding: 0 10px; width: 27.5%; margin-bottom: 10px; margin-top: 10px; }
+.scrolling.has-error { border-color: #a94442; }
+.help-block.text-danger { color: #a94442; }
+.tooltip-inner code { color: #fff; }
+.text-danger > code { color: #a94442; }
+dd.variable-list .glyphicon-question-sign { font-size: 14px; }
+dd.variable-list .glyphicon-edit { font-size: 16px; }
+dt .glyphicon-trash { margin-left: 5px; font-size: 16px; }
+#change-package_classes-form .checkbox { margin-top: 5px; }
+#variable-form h5 { margin-top: 0; }
+#variable-form .col-md-5 { padding-left: 45px; }
+
+/* Create a class for additional top margin that we can use in headings */
+.top-air { margin-top: 40px; }
+
+/* Add some bottom margin to our h2's */
+h2 { margin-bottom: 25px; }
+
+/* Style the typeahead */
+.tt-menu { min-width: 400px; padding-bottom: 10px; }
+.tt-suggestion { padding: 5px 10px; }
+.tt-suggestion:hover,
+.tt-suggestion:active { background-color: #f5f5f5; cursor: pointer; }
+
+/* Style the import layer form controls*/
+legend { border: none; }
+fieldset.fields-apart-from-layer-name { margin-top: 20px; }
+.radioLegend { margin-bottom: 0; }
+#layer-name-ctrl { margin-top: 20px; }
+#import-layer-name,
+#layer-subdir { width: 20%; }
+#layer-git-repo-url { width: 40%; }
+#layer-git-ref { width: 32%; }
+#local-dir-path { width: 45%; }
+#layer-dependency { width: 16em; }
+#layer-deps-list { margin-top: 0; }
+#form-actions { margin-bottom: 30px; }
+#duplicate-layer-info dl { margin-top: 10px; }
+#duplicate-layer-info dd { margin-bottom: 10px; }
+.help-inline { color: #737373; margin-left: 10px; }
+.radio-help { width: 50%; margin-left: 20px; }
+#repo-select div:nth-of-type(2) { margin-top: 15px; }
+
+/* Give some padding to the in-cell tooltips we use for notifications in tables */
+td > .tooltip-inner,
+.inline-notification { padding: 10px; }
+
+/* Set sane widths for table columns */
+#newcustomimagestable .get_description_or_summary,
+#imagerecipestable .get_description_or_summary,
+#softwarerecipestable .get_description_or_summary,
+#layerstable .layer__summary { width: 30%; }
+#recipestable .get_description_or_summary { width: 40%; }
+#machinestable .name { white-space: nowrap; }
+#machinestable .description { width: 45%; }
+#otable .variable_value,
+#otable .file { word-break: break-all; width: 25%; }
+[id^="variable-"] .file { word-break: break-all; }
+
+/* For the tables still not ported to ToasterTables, style the table headings
+ * that are not sortable */
+th > span.text-muted { font-weight: normal; }
+
+/* Override the rather ugly default code styles */
+code { color: #333; background-color: transparent; }
+
+/* Style our breadcrumbs */
+.breadcrumb > li + li::before { content: none; }
+.breadcrumb { background-color: transparent; padding-left: 0; padding-top: 15px; }
+.breadcrumb .divider { color: #777; margin: 0 5px; }
+
+/* Reduce top margin for the page-header class */
+.page-header { margin-top: 30px; }
+
+/* Set some space around the layer button in the layer details pages */
+.tab-content { margin-top: 20px; }
+.tab-pane { margin-top: 20px; }
+
+/* Style the new window icons */
+.glyphicon-new-window:hover { text-decoration: none; }
+.dl-horizontal > dd > .glyphicon-new-window { margin-left: 5px; }
+
+/* Style the special no results message in the custom image details page */
+[id^="no-results-special-"] > .alert-warning > ol { margin-top: 10px; }
+
+/* style the loading spinner in the new custom image dialog */
+#create-new-custom-image-btn [data-role="loading-state"] {
+ padding-left: 16px;
}
-.animate-repeat.ng-leave.ng-leave-active,
-.animate-repeat.ng-move,
-.animate-repeat.ng-enter {
- opacity:0;
+/* icon has to be absolutely positioned, otherwise the spin animation doesn't work */
+#create-new-custom-image-btn [data-role="loading-state"] .icon-spinner {
+ position: absolute;
+ left: 26px;
+ bottom: 26px;
}
-.animate-repeat.ng-leave,
-.animate-repeat.ng-enter.ng-enter-active {
- opacity:1;
-}
+/* Style the content of modal dialogs */
+.modal-footer { text-align: left; }
+.date-filter-controls { margin-top: 10px; }
+.date-filter-controls span { margin: 0 10px; }
-.tab-pane table { margin-top: 10px; }
+/* Style the fixed positioned notifications */
+#loading-notification { position: fixed; z-index: 1101; top: 3%; left: 40%; right: 40%; -webkit-box-shadow: 0 0 10px #c09853; -moz-box-shadow: 0 0 10px #c09853; box-shadow: 0 0 10px #c09853; }
-thead .description, .get_description_or_summary { width: 364px; }
-thead .add-del-layers { width: 124px; }
+.change-notification { position: fixed; z-index: 1101; top: 4%; left: 30%; right: 30%; -webkit-box-shadow: 0 0 10px #3a87ad; -moz-box-shadow: 0 0 10px #3a87ad; box-shadow: 0 0 10px #3a87ad; }
-#loading-notification {
- position: fixed;
- z-index: 101;
- top: 3%;
- left: 40%;
- right: 40%;
- -webkit-box-shadow: 0 0 10px #c09853;
- -moz-box-shadow: 0 0 10px #c09853;
- box-shadow: 0 0 10px #c09853;
-}
+.alert-success.change-notification { -webkit-box-shadow: 0 0 10px #3c763d; -moz-box-shadow: 0 0 10px #3c763d; box-shadow: 0 0 10px #3c763d; }
-#change-notification {
- position: fixed;
- z-index: 101;
- top: 3%;
- left: 20%;
- right: 20%;
- -webkit-box-shadow: 0 0 10px #3a87ad;
- -moz-box-shadow: 0 0 10px #3a87ad;
- box-shadow: 0 0 10px #3a87ad;
-}
+/* Style the new project form */
+#new-project-name { width: 33%; }
+#projectversion { width: 20%; margin-bottom: 10px; }
+
+/* Style the Toaster screenshot in the landing page */
+.img-thumbnail { padding: 0; }
+
+/* Set the layout for the build information pages */
+
+#nav { margin-top: 10px; }
+.page-header.build-data { margin-top: 0px; }
+.build-data > h1 { margin-top: 8px; }
+
+/* Style the build outcome information in the build dashboard */
+.log { margin-left: 30px; }
+.show-warnings { font-weight: 700; color: #8a6d3b; }
+.show-warnings:hover { color: #66512c; }
+
+/* Style the errors and warnings information in the build dashboard */
+#errors .panel-heading { background-color: transparent; color: #843534; }
+#warnings .panel-heading { background-color: transparent; color: #8a6d3b; }
+#warnings .panel-heading a:hover { color: #66512c; }
+h2.panel-title { font-size: 30px; }
+.alert-danger pre,
+.alert-warning pre { background-color: transparent; border: none; }
+.alert-danger pre { color: #a94442; }
+#error-info pre,
+#warning-info pre { white-space: pre-wrap; }
+.alert-warning pre { color: #8a6d3b; }
+
+/* Style the wells in the build dashboard */
+.dashboard-section h3 { margin-top: 10px; margin-bottom: 20px; }
+.col-md-4.dashboard-section dd { margin-bottom: 10px; }
+
+/* Make the help in tables insivisble until you hover over the right cell */
+.hover-help { visibility: hidden; }
+
+#add-remove-layer-btn { margin-bottom: 20px; }
+
+/* Blue hightlight animation for tasks and directory structure tables */
+.highlight { -webkit-animation: target-fade 15s 1; -moz-animation: target-fade 15s 1; animation: target-fade 15s 1; }
+@-webkit-keyframes target-fade { 0% { background-color: #D9EDF7; } 25% { background-color: #D9EDF7; } 100% { background-color: white; } }
+@-moz-keyframes target-fade { 0% { background-color: #D9EDF7; } 25% { background-color: #D9EDF7; } 100% { background-color: white; } }
+@keyframes target-fade { 0% { background-color: #D9EDF7; } 25% { background-color: #D9EDF7; } 100% { background-color: white; } }
/* Copied in from newer version of Font-Awesome 4.3.0 */
.fa-spin {
@@ -330,14 +368,3 @@ thead .add-del-layers { width: 124px; }
}
}
/* End copied in from newer version of Font-Awesome 4.3.0 */
-
-.top-padded {
- padding-top: 60px;
-}
-
-input.input-lg {
- font-size: 18px;
- height: 22px;
- line-height: 1.33333;
- padding: 10px 16px;
-}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.eot b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.eot
index 423bd5d3a..b93a4953f 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.eot
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.eot
Binary files differ
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.svg b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.svg
index 446948874..94fb5490a 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.svg
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.svg
@@ -6,224 +6,283 @@
<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
<font-face units-per-em="1200" ascent="960" descent="-240" />
<missing-glyph horiz-adv-x="500" />
-<glyph />
-<glyph />
-<glyph unicode="&#xd;" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="400" />
<glyph unicode=" " />
-<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
-<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
+<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
+<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
<glyph unicode="&#xa0;" />
-<glyph unicode="&#x2000;" horiz-adv-x="652" />
-<glyph unicode="&#x2001;" horiz-adv-x="1304" />
-<glyph unicode="&#x2002;" horiz-adv-x="652" />
-<glyph unicode="&#x2003;" horiz-adv-x="1304" />
-<glyph unicode="&#x2004;" horiz-adv-x="434" />
-<glyph unicode="&#x2005;" horiz-adv-x="326" />
-<glyph unicode="&#x2006;" horiz-adv-x="217" />
-<glyph unicode="&#x2007;" horiz-adv-x="217" />
-<glyph unicode="&#x2008;" horiz-adv-x="163" />
+<glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
+<glyph unicode="&#x2000;" horiz-adv-x="650" />
+<glyph unicode="&#x2001;" horiz-adv-x="1300" />
+<glyph unicode="&#x2002;" horiz-adv-x="650" />
+<glyph unicode="&#x2003;" horiz-adv-x="1300" />
+<glyph unicode="&#x2004;" horiz-adv-x="433" />
+<glyph unicode="&#x2005;" horiz-adv-x="325" />
+<glyph unicode="&#x2006;" horiz-adv-x="216" />
+<glyph unicode="&#x2007;" horiz-adv-x="216" />
+<glyph unicode="&#x2008;" horiz-adv-x="162" />
<glyph unicode="&#x2009;" horiz-adv-x="260" />
<glyph unicode="&#x200a;" horiz-adv-x="72" />
<glyph unicode="&#x202f;" horiz-adv-x="260" />
-<glyph unicode="&#x205f;" horiz-adv-x="326" />
-<glyph unicode="&#x20ac;" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
-<glyph unicode="&#x2212;" d="M200 400h900v300h-900v-300z" />
-<glyph unicode="&#x2601;" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86t85 208q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
-<glyph unicode="&#x2709;" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
-<glyph unicode="&#x270f;" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
-<glyph unicode="&#xe000;" horiz-adv-x="500" d="M0 0z" />
-<glyph unicode="&#xe001;" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
-<glyph unicode="&#xe002;" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q17 -55 85.5 -75.5t147.5 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
-<glyph unicode="&#xe003;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
-<glyph unicode="&#xe005;" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
-<glyph unicode="&#xe006;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
-<glyph unicode="&#xe007;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
-<glyph unicode="&#xe008;" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
-<glyph unicode="&#xe009;" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
-<glyph unicode="&#xe010;" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
-<glyph unicode="&#xe011;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
-<glyph unicode="&#xe012;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
-<glyph unicode="&#xe013;" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
-<glyph unicode="&#xe014;" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
-<glyph unicode="&#xe015;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
-<glyph unicode="&#xe016;" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 299q-120 -77 -261 -77q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
-<glyph unicode="&#xe017;" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
-<glyph unicode="&#xe018;" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
-<glyph unicode="&#xe019;" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
-<glyph unicode="&#xe020;" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
-<glyph unicode="&#xe021;" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
-<glyph unicode="&#xe022;" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
-<glyph unicode="&#xe023;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
-<glyph unicode="&#xe024;" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
-<glyph unicode="&#xe025;" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
-<glyph unicode="&#xe026;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
-<glyph unicode="&#xe027;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
-<glyph unicode="&#xe028;" d="M0 25v475l200 700h800q199 -700 200 -700v-475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
-<glyph unicode="&#xe029;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
-<glyph unicode="&#xe030;" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
-<glyph unicode="&#xe031;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
-<glyph unicode="&#xe032;" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
-<glyph unicode="&#xe033;" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
-<glyph unicode="&#xe034;" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
-<glyph unicode="&#xe035;" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
-<glyph unicode="&#xe036;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
-<glyph unicode="&#xe037;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
-<glyph unicode="&#xe038;" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
-<glyph unicode="&#xe039;" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
-<glyph unicode="&#xe040;" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
-<glyph unicode="&#xe041;" d="M1 700v475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
-<glyph unicode="&#xe042;" d="M2 700v475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
-<glyph unicode="&#xe043;" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
-<glyph unicode="&#xe044;" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
-<glyph unicode="&#xe045;" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
-<glyph unicode="&#xe046;" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
-<glyph unicode="&#xe047;" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
-<glyph unicode="&#xe048;" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v70h471q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
-<glyph unicode="&#xe049;" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
-<glyph unicode="&#xe050;" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
-<glyph unicode="&#xe051;" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
-<glyph unicode="&#xe052;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
-<glyph unicode="&#xe053;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
-<glyph unicode="&#xe054;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
-<glyph unicode="&#xe055;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
-<glyph unicode="&#xe056;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
-<glyph unicode="&#xe057;" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
-<glyph unicode="&#xe058;" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
-<glyph unicode="&#xe059;" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
-<glyph unicode="&#xe060;" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
-<glyph unicode="&#xe062;" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
-<glyph unicode="&#xe063;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
-<glyph unicode="&#xe064;" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 138.5t-64 210.5zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
-<glyph unicode="&#xe065;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
-<glyph unicode="&#xe066;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
-<glyph unicode="&#xe067;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l566 567l-136 137l-430 -431l-147 147z" />
-<glyph unicode="&#xe068;" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
-<glyph unicode="&#xe069;" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
-<glyph unicode="&#xe070;" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
-<glyph unicode="&#xe071;" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
-<glyph unicode="&#xe072;" d="M200 0l900 550l-900 550v-1100z" />
-<glyph unicode="&#xe073;" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
-<glyph unicode="&#xe074;" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
-<glyph unicode="&#xe075;" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
-<glyph unicode="&#xe076;" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
-<glyph unicode="&#xe077;" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
-<glyph unicode="&#xe078;" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
-<glyph unicode="&#xe079;" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
-<glyph unicode="&#xe080;" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
-<glyph unicode="&#xe081;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
-<glyph unicode="&#xe082;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM300 500h600v200h-600v-200z" />
-<glyph unicode="&#xe083;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141z" />
-<glyph unicode="&#xe084;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
-<glyph unicode="&#xe085;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM363 700h144q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5q19 0 30 -10t11 -26 q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-105 0 -172 -56t-67 -183zM500 300h200v100h-200v-100z" />
-<glyph unicode="&#xe086;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
-<glyph unicode="&#xe087;" d="M0 500v200h194q15 60 36 104.5t55.5 86t88 69t126.5 40.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200 v-206q149 48 201 206h-201v200h200q-25 74 -76 127.5t-124 76.5v-204h-200v203q-75 -24 -130 -77.5t-79 -125.5h209v-200h-210z" />
-<glyph unicode="&#xe088;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
-<glyph unicode="&#xe089;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
-<glyph unicode="&#xe090;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
-<glyph unicode="&#xe091;" d="M0 547l600 453v-300h600v-300h-600v-301z" />
-<glyph unicode="&#xe092;" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
-<glyph unicode="&#xe093;" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
-<glyph unicode="&#xe094;" d="M104 600h296v600h300v-600h298l-449 -600z" />
-<glyph unicode="&#xe095;" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
-<glyph unicode="&#xe096;" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
-<glyph unicode="&#xe097;" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
-<glyph unicode="&#xe101;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-33 14.5h-207q-20 0 -32 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
-<glyph unicode="&#xe102;" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111v6t-1 15t-3 18l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6h-111v-100z M100 0h400v400h-400v-400zM200 900q-3 0 14 48t35 96l18 47l214 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
-<glyph unicode="&#xe103;" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
-<glyph unicode="&#xe104;" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
-<glyph unicode="&#xe105;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
-<glyph unicode="&#xe106;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
-<glyph unicode="&#xe107;" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 33 -48 36t-48 -29l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
-<glyph unicode="&#xe108;" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -21 -13 -29t-32 1l-94 78h-222l-94 -78q-19 -9 -32 -1t-13 29v64 q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
-<glyph unicode="&#xe109;" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
-<glyph unicode="&#xe110;" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
-<glyph unicode="&#xe111;" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
-<glyph unicode="&#xe112;" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
-<glyph unicode="&#xe113;" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
-<glyph unicode="&#xe114;" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
-<glyph unicode="&#xe115;" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
-<glyph unicode="&#xe116;" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
-<glyph unicode="&#xe117;" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
-<glyph unicode="&#xe118;" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
-<glyph unicode="&#xe119;" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
-<glyph unicode="&#xe120;" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
-<glyph unicode="&#xe121;" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
-<glyph unicode="&#xe122;" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM99 500v250v5q0 13 0.5 18.5t2.5 13t8 10.5t15 3h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35q-56 337 -56 351z M1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
-<glyph unicode="&#xe123;" d="M74 350q0 21 13.5 35.5t33.5 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-22 -9 -63 -23t-167.5 -37 t-251.5 -23t-245.5 20.5t-178.5 41.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
-<glyph unicode="&#xe124;" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
-<glyph unicode="&#xe125;" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q123 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 212l100 213h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
-<glyph unicode="&#xe126;" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q123 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
-<glyph unicode="&#xe127;" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
-<glyph unicode="&#xe128;" d="M-101 651q0 72 54 110t139 37h302l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 16.5 -10.5t26 -26t16.5 -36.5v-526q0 -13 -85.5 -93.5t-93.5 -80.5h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l106 89v502l-342 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM999 201v600h200v-600h-200z" />
-<glyph unicode="&#xe129;" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6v7.5v7v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
-<glyph unicode="&#xe130;" d="M1 585q-15 -31 7 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85l-1 -302q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM76 565l237 339h503l89 -100v-294l-340 -130 q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
-<glyph unicode="&#xe131;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 500h300l-2 -194l402 294l-402 298v-197h-298v-201z" />
-<glyph unicode="&#xe132;" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l400 -294v194h302v201h-300v197z" />
-<glyph unicode="&#xe133;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
-<glyph unicode="&#xe134;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
-<glyph unicode="&#xe135;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -34 5.5 -93t7.5 -87q0 -9 17 -44t16 -60q12 0 23 -5.5 t23 -15t20 -13.5q20 -10 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55.5t-20 -57.5q12 -21 22.5 -34.5t28 -27t36.5 -17.5q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q101 -2 221 111q31 30 47 48t34 49t21 62q-14 9 -37.5 9.5t-35.5 7.5q-14 7 -49 15t-52 19 q-9 0 -39.5 -0.5t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q8 16 22 22q6 -1 26 -1.5t33.5 -4.5t19.5 -13q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5 t5.5 57.5q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 41 1 44q31 -13 58.5 -14.5t39.5 3.5l11 4q6 36 -17 53.5t-64 28.5t-56 23 q-19 -3 -37 0q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -46 0t-45 -3q-20 -6 -51.5 -25.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79zM518 915q3 12 16 30.5t16 25.5q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -18 8 -42.5t16.5 -44 t9.5 -23.5q-6 1 -39 5t-53.5 10t-36.5 16z" />
-<glyph unicode="&#xe136;" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
-<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
-<glyph unicode="&#xe138;" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
-<glyph unicode="&#xe139;" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
-<glyph unicode="&#xe140;" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
-<glyph unicode="&#xe141;" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM513 609q0 32 21 56.5t52 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-16 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5q-37 0 -62.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
-<glyph unicode="&#xe142;" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -79.5 -17t-67.5 -51l-388 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23q38 0 53 -36 q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60l517 511 q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
-<glyph unicode="&#xe143;" d="M79 784q0 131 99 229.5t230 98.5q144 0 242 -129q103 129 245 129q130 0 227 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100l-84.5 84.5t-68 74t-60 78t-33.5 70.5t-15 78z M250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-106 48.5q-73 0 -131 -83l-118 -171l-114 174q-51 80 -124 80q-59 0 -108.5 -49.5t-49.5 -118.5z" />
-<glyph unicode="&#xe144;" d="M57 353q0 -94 66 -160l141 -141q66 -66 159 -66q95 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-12 12 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141l19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -18q46 -46 77 -99l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
-<glyph unicode="&#xe145;" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
-<glyph unicode="&#xe146;" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
-<glyph unicode="&#xe148;" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335l-27 7q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5v-307l64 -14 q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5zM700 237 q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
-<glyph unicode="&#xe149;" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -11 2.5 -24.5t5.5 -24t9.5 -26.5t10.5 -25t14 -27.5t14 -25.5 t15.5 -27t13.5 -24h242v-100h-197q8 -50 -2.5 -115t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q32 1 102 -16t104 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10 t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5t-30 142.5h-221z" />
-<glyph unicode="&#xe150;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
-<glyph unicode="&#xe151;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
-<glyph unicode="&#xe152;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
-<glyph unicode="&#xe153;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
-<glyph unicode="&#xe154;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
-<glyph unicode="&#xe155;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
-<glyph unicode="&#xe156;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
-<glyph unicode="&#xe157;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
-<glyph unicode="&#xe158;" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
-<glyph unicode="&#xe159;" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
-<glyph unicode="&#xe160;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
-<glyph unicode="&#xe161;" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
-<glyph unicode="&#xe162;" d="M216 519q10 -19 32 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8l9 -1q13 0 26 16l538 630q15 19 6 36q-8 18 -32 16h-300q1 4 78 219.5t79 227.5q2 17 -6 27l-8 8h-9q-16 0 -25 -15q-4 -5 -98.5 -111.5t-228 -257t-209.5 -238.5q-17 -19 -7 -40z" />
-<glyph unicode="&#xe163;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
-<glyph unicode="&#xe164;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
-<glyph unicode="&#xe165;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
-<glyph unicode="&#xe166;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
-<glyph unicode="&#xe167;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
-<glyph unicode="&#xe168;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
-<glyph unicode="&#xe169;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 401h700v699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
-<glyph unicode="&#xe170;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l248 -237v700h-699zM900 150h100v50h-100v-50z" />
-<glyph unicode="&#xe171;" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
-<glyph unicode="&#xe172;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
-<glyph unicode="&#xe173;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
-<glyph unicode="&#xe174;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
-<glyph unicode="&#xe175;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
-<glyph unicode="&#xe176;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
-<glyph unicode="&#xe177;" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
-<glyph unicode="&#xe178;" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
-<glyph unicode="&#xe179;" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -117q-25 -16 -43.5 -50.5t-18.5 -65.5v-359z" />
-<glyph unicode="&#xe180;" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
-<glyph unicode="&#xe181;" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
-<glyph unicode="&#xe182;" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q16 17 13 40.5t-22 37.5l-192 136q-19 14 -45 12t-42 -19l-119 -118q-143 103 -267 227q-126 126 -227 268l118 118q17 17 20 41.5 t-11 44.5l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
-<glyph unicode="&#xe183;" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -15 -35.5t-35 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
-<glyph unicode="&#xe184;" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
-<glyph unicode="&#xe185;" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
-<glyph unicode="&#xe186;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
-<glyph unicode="&#xe187;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
-<glyph unicode="&#xe188;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
-<glyph unicode="&#xe189;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
-<glyph unicode="&#xe190;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
-<glyph unicode="&#xe191;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
-<glyph unicode="&#xe192;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
-<glyph unicode="&#xe193;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
-<glyph unicode="&#xe194;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
-<glyph unicode="&#xe195;" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
-<glyph unicode="&#xe197;" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86t85 208q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300 h200l-300 -300z" />
-<glyph unicode="&#xe198;" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104t60.5 178q0 121 -85 207.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
-<glyph unicode="&#xe199;" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
-<glyph unicode="&#xe200;" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -12t1 -11q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
+<glyph unicode="&#x205f;" horiz-adv-x="325" />
+<glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
+<glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
+<glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
+<glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
+<glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
+<glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
+<glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
+<glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
+<glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
+<glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
+<glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
+<glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
+<glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
+<glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
+<glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
+<glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
+<glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
+<glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
+<glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
+<glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
+<glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
+<glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
+<glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
+<glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
+<glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
+<glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
+<glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
+<glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
+<glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
+<glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
+<glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
+<glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
+<glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
+<glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
+<glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
+<glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
+<glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
+<glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
+<glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
+<glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
+<glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
+<glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
+<glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
+<glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
+<glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
+<glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
+<glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
+<glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
+<glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
+<glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
+<glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
+<glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
+<glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
+<glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
+<glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
+<glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
+<glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
+<glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
+<glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
+<glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
+<glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
+<glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
+<glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
+<glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
+<glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
+<glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
+<glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
+<glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
+<glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
+<glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
+<glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
+<glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
+<glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
+<glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
+<glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
+<glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
+<glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
+<glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
+<glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
+<glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
+<glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
+<glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
+<glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
+<glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
+<glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
+<glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
+<glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
+<glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
+<glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
+<glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
+<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
+<glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
+<glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
+<glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
+<glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
+<glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
+<glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
+<glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
+<glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
+<glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
+<glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
+<glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
+<glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
+<glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
+<glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
+<glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
+<glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
+<glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
+<glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
+<glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
+<glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
+<glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
+<glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
+<glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
+<glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
+<glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
+<glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
+<glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
+<glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
+<glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
+<glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
+<glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
+<glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
+<glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
+<glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
+<glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
+<glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
+<glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
+<glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
+<glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
+<glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
+<glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
+<glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
+<glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
+<glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
+<glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
+<glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
+<glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
+<glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
+<glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
+<glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
+<glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
+<glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
+<glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
+<glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
+<glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
+<glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
+<glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
+<glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
+<glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
+<glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
+<glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
+<glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
+<glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
+<glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
+<glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
+<glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
+<glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
+<glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
+<glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
+<glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
+<glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
+<glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
+<glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
+<glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
+<glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
+<glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
+<glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
+<glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
+<glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
+<glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
+<glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
+<glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
+<glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
</font>
</defs></svg> \ No newline at end of file
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.ttf b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.ttf
index a498ef4e7..1413fc609 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.ttf
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.ttf
Binary files differ
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woff b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woff
index d83c539b8..9e612858f 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woff
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woff
Binary files differ
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woff2 b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woff2
new file mode 100644
index 000000000..64539b54c
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/fonts/glyphicons-halflings-regular.woff2
Binary files differ
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html
index e1dba4358..e843d8d85 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/html/layer_deps_modal.html
@@ -1,17 +1,21 @@
-<div id="dependencies-modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="false">
- <form id="dependencies-modal-form">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
- <h3><span id="title"></span> dependencies</h3>
- </div>
- <div class="modal-body">
- <p id="body-text"> <strong id="layer-name"></strong> depends on some layers that are not added to your project. Select the ones you want to add:</p>
- <ul class="unstyled" id="dependencies-list">
- </ul>
- </div>
- <div class="modal-footer">
- <button class="btn btn-primary" type="submit">Add layers</button>
- <button class="btn" type="reset" data-dismiss="modal">Cancel</button>
- </div>
- </form>
-</div>
+<div id="dependencies-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <form id="dependencies-modal-form">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
+ <h3><span id="title"></span> dependencies</h3>
+ </div>
+ <div class="modal-body">
+ <p id="body-text"> <strong id="layer-name"></strong> depends on some layers that are not added to your project. Select the ones you want to add:</p>
+ <ul class="list-unstyled" id="dependencies-list">
+ </ul>
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-primary" type="submit">Add layers</button>
+ <button class="btn btn-link" type="reset" data-dismiss="modal">Cancel</button>
+ </div>
+ </form>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/img/glyphicons-halflings-white.png b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/img/glyphicons-halflings-white.png
deleted file mode 100644
index 3bf6484a2..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/img/glyphicons-halflings-white.png
+++ /dev/null
Binary files differ
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/img/glyphicons-halflings.png b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/img/glyphicons-halflings.png
deleted file mode 100644
index a99699932..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/img/glyphicons-halflings.png
+++ /dev/null
Binary files differ
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.js
new file mode 100644
index 000000000..d47d640fe
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.js
@@ -0,0 +1,2363 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+
+if (typeof jQuery === 'undefined') {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery')
+}
+
++function ($) {
+ 'use strict';
+ var version = $.fn.jquery.split(' ')[0].split('.')
+ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')
+ }
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: transition.js v3.3.6
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+ // ============================================================
+
+ function transitionEnd() {
+ var el = document.createElement('bootstrap')
+
+ var transEndEventNames = {
+ WebkitTransition : 'webkitTransitionEnd',
+ MozTransition : 'transitionend',
+ OTransition : 'oTransitionEnd otransitionend',
+ transition : 'transitionend'
+ }
+
+ for (var name in transEndEventNames) {
+ if (el.style[name] !== undefined) {
+ return { end: transEndEventNames[name] }
+ }
+ }
+
+ return false // explicit for ie8 ( ._.)
+ }
+
+ // http://blog.alexmaccaw.com/css-transitions
+ $.fn.emulateTransitionEnd = function (duration) {
+ var called = false
+ var $el = this
+ $(this).one('bsTransitionEnd', function () { called = true })
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+ setTimeout(callback, duration)
+ return this
+ }
+
+ $(function () {
+ $.support.transition = transitionEnd()
+
+ if (!$.support.transition) return
+
+ $.event.special.bsTransitionEnd = {
+ bindType: $.support.transition.end,
+ delegateType: $.support.transition.end,
+ handle: function (e) {
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
+ }
+ }
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: alert.js v3.3.6
+ * http://getbootstrap.com/javascript/#alerts
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // ALERT CLASS DEFINITION
+ // ======================
+
+ var dismiss = '[data-dismiss="alert"]'
+ var Alert = function (el) {
+ $(el).on('click', dismiss, this.close)
+ }
+
+ Alert.VERSION = '3.3.6'
+
+ Alert.TRANSITION_DURATION = 150
+
+ Alert.prototype.close = function (e) {
+ var $this = $(this)
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ var $parent = $(selector)
+
+ if (e) e.preventDefault()
+
+ if (!$parent.length) {
+ $parent = $this.closest('.alert')
+ }
+
+ $parent.trigger(e = $.Event('close.bs.alert'))
+
+ if (e.isDefaultPrevented()) return
+
+ $parent.removeClass('in')
+
+ function removeElement() {
+ // detach from parent, fire event then clean up data
+ $parent.detach().trigger('closed.bs.alert').remove()
+ }
+
+ $.support.transition && $parent.hasClass('fade') ?
+ $parent
+ .one('bsTransitionEnd', removeElement)
+ .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
+ removeElement()
+ }
+
+
+ // ALERT PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.alert')
+
+ if (!data) $this.data('bs.alert', (data = new Alert(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.alert
+
+ $.fn.alert = Plugin
+ $.fn.alert.Constructor = Alert
+
+
+ // ALERT NO CONFLICT
+ // =================
+
+ $.fn.alert.noConflict = function () {
+ $.fn.alert = old
+ return this
+ }
+
+
+ // ALERT DATA-API
+ // ==============
+
+ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: button.js v3.3.6
+ * http://getbootstrap.com/javascript/#buttons
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // BUTTON PUBLIC CLASS DEFINITION
+ // ==============================
+
+ var Button = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Button.DEFAULTS, options)
+ this.isLoading = false
+ }
+
+ Button.VERSION = '3.3.6'
+
+ Button.DEFAULTS = {
+ loadingText: 'loading...'
+ }
+
+ Button.prototype.setState = function (state) {
+ var d = 'disabled'
+ var $el = this.$element
+ var val = $el.is('input') ? 'val' : 'html'
+ var data = $el.data()
+
+ state += 'Text'
+
+ if (data.resetText == null) $el.data('resetText', $el[val]())
+
+ // push to event loop to allow forms to submit
+ setTimeout($.proxy(function () {
+ $el[val](data[state] == null ? this.options[state] : data[state])
+
+ if (state == 'loadingText') {
+ this.isLoading = true
+ $el.addClass(d).attr(d, d)
+ } else if (this.isLoading) {
+ this.isLoading = false
+ $el.removeClass(d).removeAttr(d)
+ }
+ }, this), 0)
+ }
+
+ Button.prototype.toggle = function () {
+ var changed = true
+ var $parent = this.$element.closest('[data-toggle="buttons"]')
+
+ if ($parent.length) {
+ var $input = this.$element.find('input')
+ if ($input.prop('type') == 'radio') {
+ if ($input.prop('checked')) changed = false
+ $parent.find('.active').removeClass('active')
+ this.$element.addClass('active')
+ } else if ($input.prop('type') == 'checkbox') {
+ if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
+ this.$element.toggleClass('active')
+ }
+ $input.prop('checked', this.$element.hasClass('active'))
+ if (changed) $input.trigger('change')
+ } else {
+ this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
+ this.$element.toggleClass('active')
+ }
+ }
+
+
+ // BUTTON PLUGIN DEFINITION
+ // ========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.button')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.button', (data = new Button(this, options)))
+
+ if (option == 'toggle') data.toggle()
+ else if (option) data.setState(option)
+ })
+ }
+
+ var old = $.fn.button
+
+ $.fn.button = Plugin
+ $.fn.button.Constructor = Button
+
+
+ // BUTTON NO CONFLICT
+ // ==================
+
+ $.fn.button.noConflict = function () {
+ $.fn.button = old
+ return this
+ }
+
+
+ // BUTTON DATA-API
+ // ===============
+
+ $(document)
+ .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ var $btn = $(e.target)
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
+ Plugin.call($btn, 'toggle')
+ if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
+ })
+ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: carousel.js v3.3.6
+ * http://getbootstrap.com/javascript/#carousel
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CAROUSEL CLASS DEFINITION
+ // =========================
+
+ var Carousel = function (element, options) {
+ this.$element = $(element)
+ this.$indicators = this.$element.find('.carousel-indicators')
+ this.options = options
+ this.paused = null
+ this.sliding = null
+ this.interval = null
+ this.$active = null
+ this.$items = null
+
+ this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
+
+ this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
+ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
+ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
+ }
+
+ Carousel.VERSION = '3.3.6'
+
+ Carousel.TRANSITION_DURATION = 600
+
+ Carousel.DEFAULTS = {
+ interval: 5000,
+ pause: 'hover',
+ wrap: true,
+ keyboard: true
+ }
+
+ Carousel.prototype.keydown = function (e) {
+ if (/input|textarea/i.test(e.target.tagName)) return
+ switch (e.which) {
+ case 37: this.prev(); break
+ case 39: this.next(); break
+ default: return
+ }
+
+ e.preventDefault()
+ }
+
+ Carousel.prototype.cycle = function (e) {
+ e || (this.paused = false)
+
+ this.interval && clearInterval(this.interval)
+
+ this.options.interval
+ && !this.paused
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+
+ return this
+ }
+
+ Carousel.prototype.getItemIndex = function (item) {
+ this.$items = item.parent().children('.item')
+ return this.$items.index(item || this.$active)
+ }
+
+ Carousel.prototype.getItemForDirection = function (direction, active) {
+ var activeIndex = this.getItemIndex(active)
+ var willWrap = (direction == 'prev' && activeIndex === 0)
+ || (direction == 'next' && activeIndex == (this.$items.length - 1))
+ if (willWrap && !this.options.wrap) return active
+ var delta = direction == 'prev' ? -1 : 1
+ var itemIndex = (activeIndex + delta) % this.$items.length
+ return this.$items.eq(itemIndex)
+ }
+
+ Carousel.prototype.to = function (pos) {
+ var that = this
+ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
+
+ if (pos > (this.$items.length - 1) || pos < 0) return
+
+ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
+ if (activeIndex == pos) return this.pause().cycle()
+
+ return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
+ }
+
+ Carousel.prototype.pause = function (e) {
+ e || (this.paused = true)
+
+ if (this.$element.find('.next, .prev').length && $.support.transition) {
+ this.$element.trigger($.support.transition.end)
+ this.cycle(true)
+ }
+
+ this.interval = clearInterval(this.interval)
+
+ return this
+ }
+
+ Carousel.prototype.next = function () {
+ if (this.sliding) return
+ return this.slide('next')
+ }
+
+ Carousel.prototype.prev = function () {
+ if (this.sliding) return
+ return this.slide('prev')
+ }
+
+ Carousel.prototype.slide = function (type, next) {
+ var $active = this.$element.find('.item.active')
+ var $next = next || this.getItemForDirection(type, $active)
+ var isCycling = this.interval
+ var direction = type == 'next' ? 'left' : 'right'
+ var that = this
+
+ if ($next.hasClass('active')) return (this.sliding = false)
+
+ var relatedTarget = $next[0]
+ var slideEvent = $.Event('slide.bs.carousel', {
+ relatedTarget: relatedTarget,
+ direction: direction
+ })
+ this.$element.trigger(slideEvent)
+ if (slideEvent.isDefaultPrevented()) return
+
+ this.sliding = true
+
+ isCycling && this.pause()
+
+ if (this.$indicators.length) {
+ this.$indicators.find('.active').removeClass('active')
+ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
+ $nextIndicator && $nextIndicator.addClass('active')
+ }
+
+ var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ $next.addClass(type)
+ $next[0].offsetWidth // force reflow
+ $active.addClass(direction)
+ $next.addClass(direction)
+ $active
+ .one('bsTransitionEnd', function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active')
+ $active.removeClass(['active', direction].join(' '))
+ that.sliding = false
+ setTimeout(function () {
+ that.$element.trigger(slidEvent)
+ }, 0)
+ })
+ .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
+ } else {
+ $active.removeClass('active')
+ $next.addClass('active')
+ this.sliding = false
+ this.$element.trigger(slidEvent)
+ }
+
+ isCycling && this.cycle()
+
+ return this
+ }
+
+
+ // CAROUSEL PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.carousel')
+ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
+ var action = typeof option == 'string' ? option : options.slide
+
+ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
+ if (typeof option == 'number') data.to(option)
+ else if (action) data[action]()
+ else if (options.interval) data.pause().cycle()
+ })
+ }
+
+ var old = $.fn.carousel
+
+ $.fn.carousel = Plugin
+ $.fn.carousel.Constructor = Carousel
+
+
+ // CAROUSEL NO CONFLICT
+ // ====================
+
+ $.fn.carousel.noConflict = function () {
+ $.fn.carousel = old
+ return this
+ }
+
+
+ // CAROUSEL DATA-API
+ // =================
+
+ var clickHandler = function (e) {
+ var href
+ var $this = $(this)
+ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
+ if (!$target.hasClass('carousel')) return
+ var options = $.extend({}, $target.data(), $this.data())
+ var slideIndex = $this.attr('data-slide-to')
+ if (slideIndex) options.interval = false
+
+ Plugin.call($target, options)
+
+ if (slideIndex) {
+ $target.data('bs.carousel').to(slideIndex)
+ }
+
+ e.preventDefault()
+ }
+
+ $(document)
+ .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
+ .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
+
+ $(window).on('load', function () {
+ $('[data-ride="carousel"]').each(function () {
+ var $carousel = $(this)
+ Plugin.call($carousel, $carousel.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: collapse.js v3.3.6
+ * http://getbootstrap.com/javascript/#collapse
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // COLLAPSE PUBLIC CLASS DEFINITION
+ // ================================
+
+ var Collapse = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Collapse.DEFAULTS, options)
+ this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
+ '[data-toggle="collapse"][data-target="#' + element.id + '"]')
+ this.transitioning = null
+
+ if (this.options.parent) {
+ this.$parent = this.getParent()
+ } else {
+ this.addAriaAndCollapsedClass(this.$element, this.$trigger)
+ }
+
+ if (this.options.toggle) this.toggle()
+ }
+
+ Collapse.VERSION = '3.3.6'
+
+ Collapse.TRANSITION_DURATION = 350
+
+ Collapse.DEFAULTS = {
+ toggle: true
+ }
+
+ Collapse.prototype.dimension = function () {
+ var hasWidth = this.$element.hasClass('width')
+ return hasWidth ? 'width' : 'height'
+ }
+
+ Collapse.prototype.show = function () {
+ if (this.transitioning || this.$element.hasClass('in')) return
+
+ var activesData
+ var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
+
+ if (actives && actives.length) {
+ activesData = actives.data('bs.collapse')
+ if (activesData && activesData.transitioning) return
+ }
+
+ var startEvent = $.Event('show.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ if (actives && actives.length) {
+ Plugin.call(actives, 'hide')
+ activesData || actives.data('bs.collapse', null)
+ }
+
+ var dimension = this.dimension()
+
+ this.$element
+ .removeClass('collapse')
+ .addClass('collapsing')[dimension](0)
+ .attr('aria-expanded', true)
+
+ this.$trigger
+ .removeClass('collapsed')
+ .attr('aria-expanded', true)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse in')[dimension]('')
+ this.transitioning = 0
+ this.$element
+ .trigger('shown.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ var scrollSize = $.camelCase(['scroll', dimension].join('-'))
+
+ this.$element
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
+ }
+
+ Collapse.prototype.hide = function () {
+ if (this.transitioning || !this.$element.hasClass('in')) return
+
+ var startEvent = $.Event('hide.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ var dimension = this.dimension()
+
+ this.$element[dimension](this.$element[dimension]())[0].offsetHeight
+
+ this.$element
+ .addClass('collapsing')
+ .removeClass('collapse in')
+ .attr('aria-expanded', false)
+
+ this.$trigger
+ .addClass('collapsed')
+ .attr('aria-expanded', false)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.transitioning = 0
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse')
+ .trigger('hidden.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ this.$element
+ [dimension](0)
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
+ }
+
+ Collapse.prototype.toggle = function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
+
+ Collapse.prototype.getParent = function () {
+ return $(this.options.parent)
+ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
+ .each($.proxy(function (i, element) {
+ var $element = $(element)
+ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
+ }, this))
+ .end()
+ }
+
+ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
+ var isOpen = $element.hasClass('in')
+
+ $element.attr('aria-expanded', isOpen)
+ $trigger
+ .toggleClass('collapsed', !isOpen)
+ .attr('aria-expanded', isOpen)
+ }
+
+ function getTargetFromTrigger($trigger) {
+ var href
+ var target = $trigger.attr('data-target')
+ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
+
+ return $(target)
+ }
+
+
+ // COLLAPSE PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.collapse')
+ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
+ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.collapse
+
+ $.fn.collapse = Plugin
+ $.fn.collapse.Constructor = Collapse
+
+
+ // COLLAPSE NO CONFLICT
+ // ====================
+
+ $.fn.collapse.noConflict = function () {
+ $.fn.collapse = old
+ return this
+ }
+
+
+ // COLLAPSE DATA-API
+ // =================
+
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
+ var $this = $(this)
+
+ if (!$this.attr('data-target')) e.preventDefault()
+
+ var $target = getTargetFromTrigger($this)
+ var data = $target.data('bs.collapse')
+ var option = data ? 'toggle' : $this.data()
+
+ Plugin.call($target, option)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.3.6
+ * http://getbootstrap.com/javascript/#dropdowns
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // DROPDOWN CLASS DEFINITION
+ // =========================
+
+ var backdrop = '.dropdown-backdrop'
+ var toggle = '[data-toggle="dropdown"]'
+ var Dropdown = function (element) {
+ $(element).on('click.bs.dropdown', this.toggle)
+ }
+
+ Dropdown.VERSION = '3.3.6'
+
+ function getParent($this) {
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ var $parent = selector && $(selector)
+
+ return $parent && $parent.length ? $parent : $this.parent()
+ }
+
+ function clearMenus(e) {
+ if (e && e.which === 3) return
+ $(backdrop).remove()
+ $(toggle).each(function () {
+ var $this = $(this)
+ var $parent = getParent($this)
+ var relatedTarget = { relatedTarget: this }
+
+ if (!$parent.hasClass('open')) return
+
+ if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
+
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this.attr('aria-expanded', 'false')
+ $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
+ })
+ }
+
+ Dropdown.prototype.toggle = function (e) {
+ var $this = $(this)
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) {
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+ // if mobile we use a backdrop because click events don't delegate
+ $(document.createElement('div'))
+ .addClass('dropdown-backdrop')
+ .insertAfter($(this))
+ .on('click', clearMenus)
+ }
+
+ var relatedTarget = { relatedTarget: this }
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this
+ .trigger('focus')
+ .attr('aria-expanded', 'true')
+
+ $parent
+ .toggleClass('open')
+ .trigger($.Event('shown.bs.dropdown', relatedTarget))
+ }
+
+ return false
+ }
+
+ Dropdown.prototype.keydown = function (e) {
+ if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
+
+ var $this = $(this)
+
+ e.preventDefault()
+ e.stopPropagation()
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ if (!isActive && e.which != 27 || isActive && e.which == 27) {
+ if (e.which == 27) $parent.find(toggle).trigger('focus')
+ return $this.trigger('click')
+ }
+
+ var desc = ' li:not(.disabled):visible a'
+ var $items = $parent.find('.dropdown-menu' + desc)
+
+ if (!$items.length) return
+
+ var index = $items.index(e.target)
+
+ if (e.which == 38 && index > 0) index-- // up
+ if (e.which == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
+
+ $items.eq(index).trigger('focus')
+ }
+
+
+ // DROPDOWN PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.dropdown')
+
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.dropdown
+
+ $.fn.dropdown = Plugin
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ // DROPDOWN NO CONFLICT
+ // ====================
+
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old
+ return this
+ }
+
+
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
+ // ===================================
+
+ $(document)
+ .on('click.bs.dropdown.data-api', clearMenus)
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+ .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
+ .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: modal.js v3.3.6
+ * http://getbootstrap.com/javascript/#modals
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // MODAL CLASS DEFINITION
+ // ======================
+
+ var Modal = function (element, options) {
+ this.options = options
+ this.$body = $(document.body)
+ this.$element = $(element)
+ this.$dialog = this.$element.find('.modal-dialog')
+ this.$backdrop = null
+ this.isShown = null
+ this.originalBodyPad = null
+ this.scrollbarWidth = 0
+ this.ignoreBackdropClick = false
+
+ if (this.options.remote) {
+ this.$element
+ .find('.modal-content')
+ .load(this.options.remote, $.proxy(function () {
+ this.$element.trigger('loaded.bs.modal')
+ }, this))
+ }
+ }
+
+ Modal.VERSION = '3.3.6'
+
+ Modal.TRANSITION_DURATION = 300
+ Modal.BACKDROP_TRANSITION_DURATION = 150
+
+ Modal.DEFAULTS = {
+ backdrop: true,
+ keyboard: true,
+ show: true
+ }
+
+ Modal.prototype.toggle = function (_relatedTarget) {
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
+ }
+
+ Modal.prototype.show = function (_relatedTarget) {
+ var that = this
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+
+ this.$element.trigger(e)
+
+ if (this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = true
+
+ this.checkScrollbar()
+ this.setScrollbar()
+ this.$body.addClass('modal-open')
+
+ this.escape()
+ this.resize()
+
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+
+ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
+ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
+ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
+ })
+ })
+
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(that.$body) // don't move modals dom position
+ }
+
+ that.$element
+ .show()
+ .scrollTop(0)
+
+ that.adjustDialog()
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element.addClass('in')
+
+ that.enforceFocus()
+
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+
+ transition ?
+ that.$dialog // wait for modal to slide in
+ .one('bsTransitionEnd', function () {
+ that.$element.trigger('focus').trigger(e)
+ })
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ that.$element.trigger('focus').trigger(e)
+ })
+ }
+
+ Modal.prototype.hide = function (e) {
+ if (e) e.preventDefault()
+
+ e = $.Event('hide.bs.modal')
+
+ this.$element.trigger(e)
+
+ if (!this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = false
+
+ this.escape()
+ this.resize()
+
+ $(document).off('focusin.bs.modal')
+
+ this.$element
+ .removeClass('in')
+ .off('click.dismiss.bs.modal')
+ .off('mouseup.dismiss.bs.modal')
+
+ this.$dialog.off('mousedown.dismiss.bs.modal')
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$element
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ this.hideModal()
+ }
+
+ Modal.prototype.enforceFocus = function () {
+ $(document)
+ .off('focusin.bs.modal') // guard against infinite focus loop
+ .on('focusin.bs.modal', $.proxy(function (e) {
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
+ this.$element.trigger('focus')
+ }
+ }, this))
+ }
+
+ Modal.prototype.escape = function () {
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
+ e.which == 27 && this.hide()
+ }, this))
+ } else if (!this.isShown) {
+ this.$element.off('keydown.dismiss.bs.modal')
+ }
+ }
+
+ Modal.prototype.resize = function () {
+ if (this.isShown) {
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
+ } else {
+ $(window).off('resize.bs.modal')
+ }
+ }
+
+ Modal.prototype.hideModal = function () {
+ var that = this
+ this.$element.hide()
+ this.backdrop(function () {
+ that.$body.removeClass('modal-open')
+ that.resetAdjustments()
+ that.resetScrollbar()
+ that.$element.trigger('hidden.bs.modal')
+ })
+ }
+
+ Modal.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ Modal.prototype.backdrop = function (callback) {
+ var that = this
+ var animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $(document.createElement('div'))
+ .addClass('modal-backdrop ' + animate)
+ .appendTo(this.$body)
+
+ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
+ if (this.ignoreBackdropClick) {
+ this.ignoreBackdropClick = false
+ return
+ }
+ if (e.target !== e.currentTarget) return
+ this.options.backdrop == 'static'
+ ? this.$element[0].focus()
+ : this.hide()
+ }, this))
+
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+ this.$backdrop.addClass('in')
+
+ if (!callback) return
+
+ doAnimate ?
+ this.$backdrop
+ .one('bsTransitionEnd', callback)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
+
+ var callbackRemove = function () {
+ that.removeBackdrop()
+ callback && callback()
+ }
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$backdrop
+ .one('bsTransitionEnd', callbackRemove)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callbackRemove()
+
+ } else if (callback) {
+ callback()
+ }
+ }
+
+ // these following methods are used to handle overflowing modals
+
+ Modal.prototype.handleUpdate = function () {
+ this.adjustDialog()
+ }
+
+ Modal.prototype.adjustDialog = function () {
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
+
+ this.$element.css({
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
+ })
+ }
+
+ Modal.prototype.resetAdjustments = function () {
+ this.$element.css({
+ paddingLeft: '',
+ paddingRight: ''
+ })
+ }
+
+ Modal.prototype.checkScrollbar = function () {
+ var fullWindowWidth = window.innerWidth
+ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
+ var documentElementRect = document.documentElement.getBoundingClientRect()
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
+ }
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
+ this.scrollbarWidth = this.measureScrollbar()
+ }
+
+ Modal.prototype.setScrollbar = function () {
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
+ this.originalBodyPad = document.body.style.paddingRight || ''
+ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
+ }
+
+ Modal.prototype.resetScrollbar = function () {
+ this.$body.css('padding-right', this.originalBodyPad)
+ }
+
+ Modal.prototype.measureScrollbar = function () { // thx walsh
+ var scrollDiv = document.createElement('div')
+ scrollDiv.className = 'modal-scrollbar-measure'
+ this.$body.append(scrollDiv)
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+ this.$body[0].removeChild(scrollDiv)
+ return scrollbarWidth
+ }
+
+
+ // MODAL PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option, _relatedTarget) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.modal')
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option](_relatedTarget)
+ else if (options.show) data.show(_relatedTarget)
+ })
+ }
+
+ var old = $.fn.modal
+
+ $.fn.modal = Plugin
+ $.fn.modal.Constructor = Modal
+
+
+ // MODAL NO CONFLICT
+ // =================
+
+ $.fn.modal.noConflict = function () {
+ $.fn.modal = old
+ return this
+ }
+
+
+ // MODAL DATA-API
+ // ==============
+
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this)
+ var href = $this.attr('href')
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
+
+ if ($this.is('a')) e.preventDefault()
+
+ $target.one('show.bs.modal', function (showEvent) {
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
+ $target.one('hidden.bs.modal', function () {
+ $this.is(':visible') && $this.trigger('focus')
+ })
+ })
+ Plugin.call($target, option, this)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tooltip.js v3.3.6
+ * http://getbootstrap.com/javascript/#tooltip
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TOOLTIP PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Tooltip = function (element, options) {
+ this.type = null
+ this.options = null
+ this.enabled = null
+ this.timeout = null
+ this.hoverState = null
+ this.$element = null
+ this.inState = null
+
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.VERSION = '3.3.6'
+
+ Tooltip.TRANSITION_DURATION = 150
+
+ Tooltip.DEFAULTS = {
+ animation: true,
+ placement: 'top',
+ selector: false,
+ template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
+ trigger: 'hover focus',
+ title: '',
+ delay: 0,
+ html: false,
+ container: false,
+ viewport: {
+ selector: 'body',
+ padding: 0
+ }
+ }
+
+ Tooltip.prototype.init = function (type, element, options) {
+ this.enabled = true
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
+ this.inState = { click: false, hover: false, focus: false }
+
+ if (this.$element[0] instanceof document.constructor && !this.options.selector) {
+ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
+ }
+
+ var triggers = this.options.trigger.split(' ')
+
+ for (var i = triggers.length; i--;) {
+ var trigger = triggers[i]
+
+ if (trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (trigger != 'manual') {
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+ }
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
+
+ Tooltip.prototype.getDefaults = function () {
+ return Tooltip.DEFAULTS
+ }
+
+ Tooltip.prototype.getOptions = function (options) {
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay,
+ hide: options.delay
+ }
+ }
+
+ return options
+ }
+
+ Tooltip.prototype.getDelegateOptions = function () {
+ var options = {}
+ var defaults = this.getDefaults()
+
+ this._options && $.each(this._options, function (key, value) {
+ if (defaults[key] != value) options[key] = value
+ })
+
+ return options
+ }
+
+ Tooltip.prototype.enter = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ if (obj instanceof $.Event) {
+ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
+ }
+
+ if (self.tip().hasClass('in') || self.hoverState == 'in') {
+ self.hoverState = 'in'
+ return
+ }
+
+ clearTimeout(self.timeout)
+
+ self.hoverState = 'in'
+
+ if (!self.options.delay || !self.options.delay.show) return self.show()
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
+
+ Tooltip.prototype.isInStateTrue = function () {
+ for (var key in this.inState) {
+ if (this.inState[key]) return true
+ }
+
+ return false
+ }
+
+ Tooltip.prototype.leave = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ if (obj instanceof $.Event) {
+ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
+ }
+
+ if (self.isInStateTrue()) return
+
+ clearTimeout(self.timeout)
+
+ self.hoverState = 'out'
+
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
+
+ Tooltip.prototype.show = function () {
+ var e = $.Event('show.bs.' + this.type)
+
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(e)
+
+ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
+ if (e.isDefaultPrevented() || !inDom) return
+ var that = this
+
+ var $tip = this.tip()
+
+ var tipId = this.getUID(this.type)
+
+ this.setContent()
+ $tip.attr('id', tipId)
+ this.$element.attr('aria-describedby', tipId)
+
+ if (this.options.animation) $tip.addClass('fade')
+
+ var placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
+
+ var autoToken = /\s?auto?\s?/i
+ var autoPlace = autoToken.test(placement)
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+
+ $tip
+ .detach()
+ .css({ top: 0, left: 0, display: 'block' })
+ .addClass(placement)
+ .data('bs.' + this.type, this)
+
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+ this.$element.trigger('inserted.bs.' + this.type)
+
+ var pos = this.getPosition()
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
+
+ if (autoPlace) {
+ var orgPlacement = placement
+ var viewportDim = this.getPosition(this.$viewport)
+
+ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
+ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
+ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
+ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
+ placement
+
+ $tip
+ .removeClass(orgPlacement)
+ .addClass(placement)
+ }
+
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+
+ this.applyPlacement(calculatedOffset, placement)
+
+ var complete = function () {
+ var prevHoverState = that.hoverState
+ that.$element.trigger('shown.bs.' + that.type)
+ that.hoverState = null
+
+ if (prevHoverState == 'out') that.leave(that)
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+ }
+ }
+
+ Tooltip.prototype.applyPlacement = function (offset, placement) {
+ var $tip = this.tip()
+ var width = $tip[0].offsetWidth
+ var height = $tip[0].offsetHeight
+
+ // manually read margins because getBoundingClientRect includes difference
+ var marginTop = parseInt($tip.css('margin-top'), 10)
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
+
+ // we must check for NaN for ie 8/9
+ if (isNaN(marginTop)) marginTop = 0
+ if (isNaN(marginLeft)) marginLeft = 0
+
+ offset.top += marginTop
+ offset.left += marginLeft
+
+ // $.fn.offset doesn't round pixel values
+ // so we use setOffset directly with our own function B-0
+ $.offset.setOffset($tip[0], $.extend({
+ using: function (props) {
+ $tip.css({
+ top: Math.round(props.top),
+ left: Math.round(props.left)
+ })
+ }
+ }, offset), 0)
+
+ $tip.addClass('in')
+
+ // check to see if placing tip in new offset caused the tip to resize itself
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
+
+ if (placement == 'top' && actualHeight != height) {
+ offset.top = offset.top + height - actualHeight
+ }
+
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
+
+ if (delta.left) offset.left += delta.left
+ else offset.top += delta.top
+
+ var isVertical = /top|bottom/.test(placement)
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
+
+ $tip.offset(offset)
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
+ }
+
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
+ this.arrow()
+ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
+ .css(isVertical ? 'top' : 'left', '')
+ }
+
+ Tooltip.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
+
+ Tooltip.prototype.hide = function (callback) {
+ var that = this
+ var $tip = $(this.$tip)
+ var e = $.Event('hide.bs.' + this.type)
+
+ function complete() {
+ if (that.hoverState != 'in') $tip.detach()
+ that.$element
+ .removeAttr('aria-describedby')
+ .trigger('hidden.bs.' + that.type)
+ callback && callback()
+ }
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ $tip.removeClass('in')
+
+ $.support.transition && $tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+
+ this.hoverState = null
+
+ return this
+ }
+
+ Tooltip.prototype.fixTitle = function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+ }
+ }
+
+ Tooltip.prototype.hasContent = function () {
+ return this.getTitle()
+ }
+
+ Tooltip.prototype.getPosition = function ($element) {
+ $element = $element || this.$element
+
+ var el = $element[0]
+ var isBody = el.tagName == 'BODY'
+
+ var elRect = el.getBoundingClientRect()
+ if (elRect.width == null) {
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
+ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
+ }
+ var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
+ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
+ }
+
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
+
+ }
+
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
+ var delta = { top: 0, left: 0 }
+ if (!this.$viewport) return delta
+
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
+ var viewportDimensions = this.getPosition(this.$viewport)
+
+ if (/right|left/.test(placement)) {
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
+ delta.top = viewportDimensions.top - topEdgeOffset
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
+ }
+ } else {
+ var leftEdgeOffset = pos.left - viewportPadding
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
+ delta.left = viewportDimensions.left - leftEdgeOffset
+ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
+ }
+ }
+
+ return delta
+ }
+
+ Tooltip.prototype.getTitle = function () {
+ var title
+ var $e = this.$element
+ var o = this.options
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+
+ return title
+ }
+
+ Tooltip.prototype.getUID = function (prefix) {
+ do prefix += ~~(Math.random() * 1000000)
+ while (document.getElementById(prefix))
+ return prefix
+ }
+
+ Tooltip.prototype.tip = function () {
+ if (!this.$tip) {
+ this.$tip = $(this.options.template)
+ if (this.$tip.length != 1) {
+ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
+ }
+ }
+ return this.$tip
+ }
+
+ Tooltip.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+ }
+
+ Tooltip.prototype.enable = function () {
+ this.enabled = true
+ }
+
+ Tooltip.prototype.disable = function () {
+ this.enabled = false
+ }
+
+ Tooltip.prototype.toggleEnabled = function () {
+ this.enabled = !this.enabled
+ }
+
+ Tooltip.prototype.toggle = function (e) {
+ var self = this
+ if (e) {
+ self = $(e.currentTarget).data('bs.' + this.type)
+ if (!self) {
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
+ $(e.currentTarget).data('bs.' + this.type, self)
+ }
+ }
+
+ if (e) {
+ self.inState.click = !self.inState.click
+ if (self.isInStateTrue()) self.enter(self)
+ else self.leave(self)
+ } else {
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+ }
+ }
+
+ Tooltip.prototype.destroy = function () {
+ var that = this
+ clearTimeout(this.timeout)
+ this.hide(function () {
+ that.$element.off('.' + that.type).removeData('bs.' + that.type)
+ if (that.$tip) {
+ that.$tip.detach()
+ }
+ that.$tip = null
+ that.$arrow = null
+ that.$viewport = null
+ })
+ }
+
+
+ // TOOLTIP PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tooltip')
+ var options = typeof option == 'object' && option
+
+ if (!data && /destroy|hide/.test(option)) return
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tooltip
+
+ $.fn.tooltip = Plugin
+ $.fn.tooltip.Constructor = Tooltip
+
+
+ // TOOLTIP NO CONFLICT
+ // ===================
+
+ $.fn.tooltip.noConflict = function () {
+ $.fn.tooltip = old
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: popover.js v3.3.6
+ * http://getbootstrap.com/javascript/#popovers
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // POPOVER PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Popover = function (element, options) {
+ this.init('popover', element, options)
+ }
+
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
+
+ Popover.VERSION = '3.3.6'
+
+ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+ placement: 'right',
+ trigger: 'click',
+ content: '',
+ template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
+ })
+
+
+ // NOTE: POPOVER EXTENDS tooltip.js
+ // ================================
+
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
+
+ Popover.prototype.constructor = Popover
+
+ Popover.prototype.getDefaults = function () {
+ return Popover.DEFAULTS
+ }
+
+ Popover.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+ var content = this.getContent()
+
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
+ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
+ ](content)
+
+ $tip.removeClass('fade top bottom left right in')
+
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
+ // this manually by checking the contents.
+ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
+ }
+
+ Popover.prototype.hasContent = function () {
+ return this.getTitle() || this.getContent()
+ }
+
+ Popover.prototype.getContent = function () {
+ var $e = this.$element
+ var o = this.options
+
+ return $e.attr('data-content')
+ || (typeof o.content == 'function' ?
+ o.content.call($e[0]) :
+ o.content)
+ }
+
+ Popover.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
+ }
+
+
+ // POPOVER PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.popover')
+ var options = typeof option == 'object' && option
+
+ if (!data && /destroy|hide/.test(option)) return
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.popover
+
+ $.fn.popover = Plugin
+ $.fn.popover.Constructor = Popover
+
+
+ // POPOVER NO CONFLICT
+ // ===================
+
+ $.fn.popover.noConflict = function () {
+ $.fn.popover = old
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: scrollspy.js v3.3.6
+ * http://getbootstrap.com/javascript/#scrollspy
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // SCROLLSPY CLASS DEFINITION
+ // ==========================
+
+ function ScrollSpy(element, options) {
+ this.$body = $(document.body)
+ this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
+ this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
+ this.selector = (this.options.target || '') + ' .nav li > a'
+ this.offsets = []
+ this.targets = []
+ this.activeTarget = null
+ this.scrollHeight = 0
+
+ this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
+ this.refresh()
+ this.process()
+ }
+
+ ScrollSpy.VERSION = '3.3.6'
+
+ ScrollSpy.DEFAULTS = {
+ offset: 10
+ }
+
+ ScrollSpy.prototype.getScrollHeight = function () {
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ }
+
+ ScrollSpy.prototype.refresh = function () {
+ var that = this
+ var offsetMethod = 'offset'
+ var offsetBase = 0
+
+ this.offsets = []
+ this.targets = []
+ this.scrollHeight = this.getScrollHeight()
+
+ if (!$.isWindow(this.$scrollElement[0])) {
+ offsetMethod = 'position'
+ offsetBase = this.$scrollElement.scrollTop()
+ }
+
+ this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this)
+ var href = $el.data('target') || $el.attr('href')
+ var $href = /^#./.test(href) && $(href)
+
+ return ($href
+ && $href.length
+ && $href.is(':visible')
+ && [[$href[offsetMethod]().top + offsetBase, href]]) || null
+ })
+ .sort(function (a, b) { return a[0] - b[0] })
+ .each(function () {
+ that.offsets.push(this[0])
+ that.targets.push(this[1])
+ })
+ }
+
+ ScrollSpy.prototype.process = function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+ var scrollHeight = this.getScrollHeight()
+ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
+ var offsets = this.offsets
+ var targets = this.targets
+ var activeTarget = this.activeTarget
+ var i
+
+ if (this.scrollHeight != scrollHeight) {
+ this.refresh()
+ }
+
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
+ }
+
+ if (activeTarget && scrollTop < offsets[0]) {
+ this.activeTarget = null
+ return this.clear()
+ }
+
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
+ && this.activate(targets[i])
+ }
+ }
+
+ ScrollSpy.prototype.activate = function (target) {
+ this.activeTarget = target
+
+ this.clear()
+
+ var selector = this.selector +
+ '[data-target="' + target + '"],' +
+ this.selector + '[href="' + target + '"]'
+
+ var active = $(selector)
+ .parents('li')
+ .addClass('active')
+
+ if (active.parent('.dropdown-menu').length) {
+ active = active
+ .closest('li.dropdown')
+ .addClass('active')
+ }
+
+ active.trigger('activate.bs.scrollspy')
+ }
+
+ ScrollSpy.prototype.clear = function () {
+ $(this.selector)
+ .parentsUntil(this.options.target, '.active')
+ .removeClass('active')
+ }
+
+
+ // SCROLLSPY PLUGIN DEFINITION
+ // ===========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.scrollspy')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.scrollspy
+
+ $.fn.scrollspy = Plugin
+ $.fn.scrollspy.Constructor = ScrollSpy
+
+
+ // SCROLLSPY NO CONFLICT
+ // =====================
+
+ $.fn.scrollspy.noConflict = function () {
+ $.fn.scrollspy = old
+ return this
+ }
+
+
+ // SCROLLSPY DATA-API
+ // ==================
+
+ $(window).on('load.bs.scrollspy.data-api', function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this)
+ Plugin.call($spy, $spy.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tab.js v3.3.6
+ * http://getbootstrap.com/javascript/#tabs
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TAB CLASS DEFINITION
+ // ====================
+
+ var Tab = function (element) {
+ // jscs:disable requireDollarBeforejQueryAssignment
+ this.element = $(element)
+ // jscs:enable requireDollarBeforejQueryAssignment
+ }
+
+ Tab.VERSION = '3.3.6'
+
+ Tab.TRANSITION_DURATION = 150
+
+ Tab.prototype.show = function () {
+ var $this = this.element
+ var $ul = $this.closest('ul:not(.dropdown-menu)')
+ var selector = $this.data('target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ if ($this.parent('li').hasClass('active')) return
+
+ var $previous = $ul.find('.active:last a')
+ var hideEvent = $.Event('hide.bs.tab', {
+ relatedTarget: $this[0]
+ })
+ var showEvent = $.Event('show.bs.tab', {
+ relatedTarget: $previous[0]
+ })
+
+ $previous.trigger(hideEvent)
+ $this.trigger(showEvent)
+
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
+
+ var $target = $(selector)
+
+ this.activate($this.closest('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $previous.trigger({
+ type: 'hidden.bs.tab',
+ relatedTarget: $this[0]
+ })
+ $this.trigger({
+ type: 'shown.bs.tab',
+ relatedTarget: $previous[0]
+ })
+ })
+ }
+
+ Tab.prototype.activate = function (element, container, callback) {
+ var $active = container.find('> .active')
+ var transition = callback
+ && $.support.transition
+ && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', false)
+
+ element
+ .addClass('active')
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+
+ if (transition) {
+ element[0].offsetWidth // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
+ }
+
+ if (element.parent('.dropdown-menu').length) {
+ element
+ .closest('li.dropdown')
+ .addClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+ }
+
+ callback && callback()
+ }
+
+ $active.length && transition ?
+ $active
+ .one('bsTransitionEnd', next)
+ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
+ next()
+
+ $active.removeClass('in')
+ }
+
+
+ // TAB PLUGIN DEFINITION
+ // =====================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tab')
+
+ if (!data) $this.data('bs.tab', (data = new Tab(this)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tab
+
+ $.fn.tab = Plugin
+ $.fn.tab.Constructor = Tab
+
+
+ // TAB NO CONFLICT
+ // ===============
+
+ $.fn.tab.noConflict = function () {
+ $.fn.tab = old
+ return this
+ }
+
+
+ // TAB DATA-API
+ // ============
+
+ var clickHandler = function (e) {
+ e.preventDefault()
+ Plugin.call($(this), 'show')
+ }
+
+ $(document)
+ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
+ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: affix.js v3.3.6
+ * http://getbootstrap.com/javascript/#affix
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // AFFIX CLASS DEFINITION
+ // ======================
+
+ var Affix = function (element, options) {
+ this.options = $.extend({}, Affix.DEFAULTS, options)
+
+ this.$target = $(this.options.target)
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
+
+ this.$element = $(element)
+ this.affixed = null
+ this.unpin = null
+ this.pinnedOffset = null
+
+ this.checkPosition()
+ }
+
+ Affix.VERSION = '3.3.6'
+
+ Affix.RESET = 'affix affix-top affix-bottom'
+
+ Affix.DEFAULTS = {
+ offset: 0,
+ target: window
+ }
+
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ var targetHeight = this.$target.height()
+
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
+
+ if (this.affixed == 'bottom') {
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
+ }
+
+ var initializing = this.affixed == null
+ var colliderTop = initializing ? scrollTop : position.top
+ var colliderHeight = initializing ? targetHeight : height
+
+ if (offsetTop != null && scrollTop <= offsetTop) return 'top'
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+
+ return false
+ }
+
+ Affix.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset) return this.pinnedOffset
+ this.$element.removeClass(Affix.RESET).addClass('affix')
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ return (this.pinnedOffset = position.top - scrollTop)
+ }
+
+ Affix.prototype.checkPositionWithEventLoop = function () {
+ setTimeout($.proxy(this.checkPosition, this), 1)
+ }
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return
+
+ var height = this.$element.height()
+ var offset = this.options.offset
+ var offsetTop = offset.top
+ var offsetBottom = offset.bottom
+ var scrollHeight = Math.max($(document).height(), $(document.body).height())
+
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
+ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
+
+ if (this.affixed != affix) {
+ if (this.unpin != null) this.$element.css('top', '')
+
+ var affixType = 'affix' + (affix ? '-' + affix : '')
+ var e = $.Event(affixType + '.bs.affix')
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ this.affixed = affix
+ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+
+ this.$element
+ .removeClass(Affix.RESET)
+ .addClass(affixType)
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
+
+ if (affix == 'bottom') {
+ this.$element.offset({
+ top: scrollHeight - height - offsetBottom
+ })
+ }
+ }
+
+
+ // AFFIX PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.affix')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.affix
+
+ $.fn.affix = Plugin
+ $.fn.affix.Constructor = Affix
+
+
+ // AFFIX NO CONFLICT
+ // =================
+
+ $.fn.affix.noConflict = function () {
+ $.fn.affix = old
+ return this
+ }
+
+
+ // AFFIX DATA-API
+ // ==============
+
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this)
+ var data = $spy.data()
+
+ data.offset = data.offset || {}
+
+ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
+ if (data.offsetTop != null) data.offset.top = data.offsetTop
+
+ Plugin.call($spy, data)
+ })
+ })
+
+}(jQuery);
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.min.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.min.js
index 848258d38..c4a924160 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.min.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/bootstrap.min.js
@@ -1,6 +1,7 @@
/*!
-* Bootstrap.js by @fat & @mdo
-* Copyright 2013 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(".dropdown-backdrop").remove(),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||("ontouchstart"in document.documentElement&&e('<div class="dropdown-backdrop"/>').insertBefore(e(this)).on("click",r),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<s.length-1&&f++,~f||(f=0),s.eq(f).focus()}};var s=e.fn.dropdown;e.fn.dropdown=function(t){return this.each(function(){var r=e(this),i=r.data("dropdown");i||r.data("dropdown",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.dropdown.Constructor=n,e.fn.dropdown.noConflict=function(){return e.fn.dropdown=s,this},e(document).on("click.dropdown.data-api",r).on("click.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("click.dropdown.data-api",t,n.prototype.toggle).on("keydown.dropdown.data-api",t+", [role=menu]",n.prototype.keydown)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=n,this.$element=e(t).delegate('[data-dismiss="modal"]',"click.dismiss.modal",e.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};t.prototype={constructor:t,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var t=this,n=e.Event("show");this.$element.trigger(n);if(this.isShown||n.isDefaultPrevented())return;this.isShown=!0,this.escape(),this.backdrop(function(){var n=e.support.transition&&t.$element.hasClass("fade");t.$element.parent().length||t.$element.appendTo(document.body),t.$element.show(),n&&t.$element[0].offsetWidth,t.$element.addClass("in").attr("aria-hidden",!1),t.enforceFocus(),n?t.$element.one(e.support.transition.end,function(){t.$element.focus().trigger("shown")}):t.$element.focus().trigger("shown")})},hide:function(t){t&&t.preventDefault();var n=this;t=e.Event("hide"),this.$element.trigger(t);if(!this.isShown||t.isDefaultPrevented())return;this.isShown=!1,this.escape(),e(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),e.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal()},enforceFocus:function(){var t=this;e(document).on("focusin.modal",function(e){t.$element[0]!==e.target&&!t.$element.has(e.target).length&&t.$element.focus()})},escape:function(){var e=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(t){t.which==27&&e.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var t=this,n=setTimeout(function(){t.$element.off(e.support.transition.end),t.hideModal()},500);this.$element.one(e.support.transition.end,function(){clearTimeout(n),t.hideModal()})},hideModal:function(){var e=this;this.$element.hide(),this.backdrop(function(){e.removeBackdrop(),e.$element.trigger("hidden")})},removeBackdrop:function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},backdrop:function(t){var n=this,r=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var i=e.support.transition&&r;this.$backdrop=e('<div class="modal-backdrop '+r+'" />').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:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',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:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),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<this.options.minLength?this.shown?this.hide():this:(n=e.isFunction(this.source)?this.source(this.query,e.proxy(this.process,this)):this.source,n?this.process(n):this)},process:function(t){var n=this;return t=e.grep(t,function(e){return n.matcher(e)}),t=this.sorter(t),t.length?this.render(t.slice(0,this.options.items)).show():this.shown?this.hide():this},matcher:function(e){return~e.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(e){var t=[],n=[],r=[],i;while(i=e.shift())i.toLowerCase().indexOf(this.query.toLowerCase())?~i.indexOf(this.query)?n.push(i):r.push(i):t.push(i);return t.concat(n,r)},highlighter:function(e){var t=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return e.replace(new RegExp("("+t+")","ig"),function(e,t){return"<strong>"+t+"</strong>"})},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:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>',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
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),
+d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/customrecipe.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/customrecipe.js
index 1c0ef9e37..9ea960288 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/customrecipe.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/customrecipe.js
@@ -158,7 +158,7 @@ function customRecipePageInit(ctx) {
msg += " <strong>" + dep.name + "</strong>";
/* Add any cells currently in view to the list of cells which get
- * an inline notification inside them and which change add/rm state
+ * an list-inline notification inside them and which change add/rm state
*/
depBtnCell = $("#package-btn-cell-" + dep.pk);
btnCell = btnCell.add(depBtnCell);
@@ -208,7 +208,7 @@ function customRecipePageInit(ctx) {
}
/* Add any cells currently in view to the list of cells which get
- * an inline notification inside them and which change add/rm state
+ * an list-inline notification inside them and which change add/rm state
*/
depBtnCell = $("#package-btn-cell-" + dep.pk);
btnCell = btnCell.add(depBtnCell);
@@ -281,4 +281,36 @@ function customRecipePageInit(ctx) {
window.location.replace(libtoaster.ctx.projectBuildsUrl);
});
});
+
+ $("#delete-custom-recipe-confirmed").click(function(e){
+ e.preventDefault();
+ libtoaster.disableAjaxLoadingTimer();
+ $(this).find('[data-role="submit-state"]').hide();
+ $(this).find('[data-role="loading-state"]').show();
+ $(this).attr("disabled", "disabled");
+
+ $.ajax({
+ type: 'DELETE',
+ url: ctx.recipe.xhrCustomRecipeUrl,
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function (data) {
+ if (data.error !== "ok") {
+ console.warn(data.error);
+ } else {
+ var msg = $('<span>You have deleted <strong>1</strong> custom image: <strong id="deleted-custom-image-name"></strong></span>');
+ msg.find("#deleted-custom-image-name").text(ctx.recipe.name);
+
+ libtoaster.setNotification("custom-image-recipe-deleted",
+ msg.html());
+
+ window.location.replace(data.gotoUrl);
+ }
+ },
+ error: function (data) {
+ console.warn(data);
+ }
+ });
+ });
+
+
}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/importlayer.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/importlayer.js
index 5a59799bc..30dc28280 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/importlayer.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/importlayer.js
@@ -10,45 +10,31 @@ function importLayerPageInit (ctx) {
var layerDepInput = $("#layer-dependency");
var layerNameCtrl = $("#layer-name-ctrl");
var duplicatedLayerName = $("#duplicated-layer-name-hint");
+ var localDirPath = $("#local-dir-path");
var layerDeps = {};
var layerDepsDeps = {};
var currentLayerDepSelection;
var validLayerName = /^(\w|-)+$/;
- libtoaster.makeTypeahead(layerDepInput, libtoaster.ctx.layersTypeAheadUrl, { include_added: "true" }, function(item){
+ libtoaster.makeTypeahead(layerDepInput,
+ libtoaster.ctx.layersTypeAheadUrl,
+ { include_added: "true" }, function(item){
currentLayerDepSelection = item;
+ layerDepBtn.removeAttr("disabled");
});
- // choices available in the typeahead
- var layerDepsChoices = {};
-
- // when the typeahead choices change, store an array of the available layer
- // choices locally, to use for enabling/disabling the "Add layer" button
- layerDepInput.on("typeahead-choices-change", function (event, data) {
- layerDepsChoices = {};
-
- if (data.choices) {
- data.choices.forEach(function (item) {
- layerDepsChoices[item.name] = item;
- });
- }
+ layerDepInput.on("typeahead:select", function(event, data){
+ currentLayerDepSelection = data;
});
+ // Disable local dir repo when page is loaded.
+ $('#local-dir').hide();
+
// disable the "Add layer" button when the layer input typeahead is empty
// or not in the typeahead choices
- layerDepInput.on("input change", function () {
- // get the choices from the typeahead
- var choice = layerDepsChoices[$(this).val()];
-
- if (choice) {
- layerDepBtn.removeAttr("disabled");
- currentLayerDepSelection = choice;
- }
- else {
- layerDepBtn.attr("disabled", "disabled");
- currentLayerDepSelection = undefined;
- }
+ layerDepInput.on("input change", function(){
+ layerDepBtn.attr("disabled","disabled");
});
/* We automatically add "openembedded-core" layer for convenience as a
@@ -70,7 +56,7 @@ function importLayerPageInit (ctx) {
layerDeps[currentLayerDepSelection.id] = currentLayerDepSelection;
/* Make a list item for the new layer dependency */
- var newLayerDep = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Delete\"></span></li>");
+ var newLayerDep = $("<li><a></a><span class=\"glyphicon glyphicon-trash\" data-toggle=\"tooltip\" title=\"Remove\"></span></li>");
newLayerDep.data('layer-id', currentLayerDepSelection.id);
newLayerDep.children("span").tooltip();
@@ -91,7 +77,8 @@ function importLayerPageInit (ctx) {
$("#layer-deps-list").append(newLayerDep);
- libtoaster.getLayerDepsForProject(currentLayerDepSelection.layerdetailurl, function (data){
+ libtoaster.getLayerDepsForProject(currentLayerDepSelection.layerdetailurl,
+ function (data){
/* These are the dependencies of the layer added as a dependency */
if (data.list.length > 0) {
currentLayerDepSelection.url = currentLayerDepSelection.layerdetailurl;
@@ -105,7 +92,8 @@ function importLayerPageInit (ctx) {
}, null);
});
- importAndAddBtn.click(function(){
+ importAndAddBtn.click(function(e){
+ e.preventDefault();
/* This is a list of the names from layerDeps for the layer deps
* modal dialog body
*/
@@ -145,7 +133,9 @@ function importLayerPageInit (ctx) {
var body = "<strong>"+layer.name+"</strong>'s dependencies ("+
depNames.join(", ")+"</span>) require some layers that are not added to your project. Select the ones you want to add:</p>";
- showLayerDepsModal(layer, depDepsArray, title, body, false, function(layerObsList){
+ showLayerDepsModal(layer,
+ depDepsArray,
+ title, body, false, function(layerObsList){
/* Add the accepted layer dependencies' ids to the allDeps array */
for (var key in layerObsList){
allDeps.push(layerObsList[key].id);
@@ -167,8 +157,16 @@ function importLayerPageInit (ctx) {
dir_path: $("#layer-subdir").val(),
project_id: libtoaster.ctx.projectId,
layer_deps: layerDepsCsv,
+ local_source_dir: $('#local-dir-path').val(),
};
+ if ($('input[name=repo]:checked').val() == "git") {
+ layerData.local_source_dir = "";
+ } else {
+ layerData.vcs_url = "";
+ layerData.git_ref = "";
+ }
+
$.ajax({
type: "POST",
url: ctx.xhrImportLayerUrl,
@@ -178,9 +176,8 @@ function importLayerPageInit (ctx) {
if (data.error != "ok") {
console.log(data.error);
} else {
- /* Success layer import now go to the project page */
- $.cookie('layer-imported-alert', JSON.stringify(data), { path: '/'});
- window.location.replace(libtoaster.ctx.projectPageUrl+'?notify=layer-imported');
+ createImportedNotification(data);
+ window.location.replace(libtoaster.ctx.projectPageUrl);
}
},
error: function (data) {
@@ -191,6 +188,30 @@ function importLayerPageInit (ctx) {
}
});
+ /* Layer imported notification */
+ function createImportedNotification(imported){
+ var message = "Layer imported";
+
+ if (imported.deps_added.length === 0) {
+ message = "You have imported <strong><a class=\"alert-link\" href=\""+imported.imported_layer.layerdetailurl+"\">"+imported.imported_layer.name+"</a></strong> and added it to your project.";
+ } else {
+
+ var links = "<a href=\""+imported.imported_layer.layerdetailurl+"\">"+imported.imported_layer.name+"</a>, ";
+
+ imported.deps_added.map (function(item, index){
+ links +='<a href="'+item.layerdetailurl+'">'+item.name+'</a>';
+ /*If we're at the last element we don't want the trailing comma */
+ if (imported.deps_added[index+1] !== undefined)
+ links += ', ';
+ });
+
+ /* Length + 1 here to do deps + the imported layer */
+ message = 'You have imported <strong><a href="'+imported.imported_layer.layerdetailurl+'">'+imported.imported_layer.name+'</a></strong> and added <strong>'+(imported.deps_added.length+1)+'</strong> layers to your project: <strong>'+links+'</strong>';
+ }
+
+ libtoaster.setNotification("layer-imported", message);
+ }
+
function enable_import_btn(enabled) {
var importAndAddHint = $("#import-and-add-hint");
@@ -207,25 +228,48 @@ function importLayerPageInit (ctx) {
function check_form() {
var valid = false;
var inputs = $("input:required");
+ var inputStr = inputs.val().split("");
- for (var i=0; i<inputs.length; i++){
- if (!(valid = inputs[i].value)){
+ for (var i=0; i<inputs.val().length; i++){
+ if (!(valid = inputStr[i])){
enable_import_btn(false);
break;
}
}
- if (valid)
- enable_import_btn(true);
+ if (valid) {
+ if ($("#local-dir-radio").prop("checked") &&
+ localDirPath.val().length > 0) {
+ enable_import_btn(true);
+ }
+
+ if ($("#git-repo-radio").prop("checked") &&
+ vcsURLInput.val().length > 0 && gitRefInput.val().length > 0) {
+ enable_import_btn(true);
+ }
+ }
+
+ if (inputs.val().length == 0)
+ enable_import_btn(false);
}
function layerExistsError(layer){
var dupLayerInfo = $("#duplicate-layer-info");
- dupLayerInfo.find(".dup-layer-name").text(layer.name);
- dupLayerInfo.find(".dup-layer-link").attr("href", layer.layerdetailurl);
- dupLayerInfo.find("#dup-layer-vcs-url").text(layer.vcs_url);
- dupLayerInfo.find("#dup-layer-revision").text(layer.vcs_reference);
+ if (layer.local_source_dir) {
+ $("#git-layer-dup").hide();
+ $("#local-layer-dup").fadeIn();
+ dupLayerInfo.find(".dup-layer-name").text(layer.name);
+ dupLayerInfo.find(".dup-layer-link").attr("href", layer.layerdetailurl);
+ dupLayerInfo.find("#dup-local-source-dir-name").text(layer.local_source_dir);
+ } else {
+ $("#git-layer-dup").fadeIn();
+ $("#local-layer-dup").hide();
+ dupLayerInfo.find(".dup-layer-name").text(layer.name);
+ dupLayerInfo.find(".dup-layer-link").attr("href", layer.layerdetailurl);
+ dupLayerInfo.find("#dup-layer-vcs-url").text(layer.vcs_url);
+ dupLayerInfo.find("#dup-layer-revision").text(layer.vcs_reference);
+ }
$(".fields-apart-from-layer-name").fadeOut(function(){
dupLayerInfo.fadeIn();
@@ -233,13 +277,13 @@ function importLayerPageInit (ctx) {
}
layerNameInput.on('blur', function() {
- if (!$(this).val()){
- return;
- }
- var name = $(this).val();
+ if (!$(this).val()){
+ return;
+ }
+ var name = $(this).val();
- /* Check if the layer name exists */
- $.getJSON(libtoaster.ctx.layersTypeAheadUrl,
+ /* Check if the layer name exists */
+ $.getJSON(libtoaster.ctx.layersTypeAheadUrl,
{ include_added: "true" , search: name, format: "json" },
function(layer) {
if (layer.results.length > 0) {
@@ -262,7 +306,7 @@ function importLayerPageInit (ctx) {
layerNameInput.on('input', function() {
if ($(this).val() && !validLayerName.test($(this).val())){
- layerNameCtrl.addClass("error")
+ layerNameCtrl.addClass("has-error")
$("#invalid-layer-name-hint").show();
enable_import_btn(false);
return;
@@ -270,16 +314,19 @@ function importLayerPageInit (ctx) {
if ($("#duplicate-layer-info").css("display") != "None"){
$("#duplicate-layer-info").fadeOut(function(){
- $(".fields-apart-from-layer-name").show();
- });
+ $(".fields-apart-from-layer-name").show();
+ radioDisplay();
+ });
- }
+ }
+
+ radioDisplay();
/* Don't remove the error class if we're displaying the error for another
* reason.
*/
if (!duplicatedLayerName.is(":visible"))
- layerNameCtrl.removeClass("error")
+ layerNameCtrl.removeClass("has-error")
$("#invalid-layer-name-hint").hide();
check_form();
@@ -300,4 +347,72 @@ function importLayerPageInit (ctx) {
}
});
+ function radioDisplay() {
+ if ($('input[name=repo]:checked').val() == "local") {
+ $('#git-repo').hide();
+ $('#import-git-layer-and-add-hint').hide();
+ $('#local-dir').fadeIn();
+ $('#import-local-dir-and-add-hint').fadeIn();
+ } else {
+ $('#local-dir').hide();
+ $('#import-local-dir-and-add-hint').hide();
+ $('#git-repo').fadeIn();
+ $('#import-git-layer-and-add-hint').fadeIn();
+ }
+ }
+
+ $('input:radio[name="repo"]').change(function() {
+ radioDisplay();
+ if ($("#local-dir-radio").prop("checked")) {
+ if (localDirPath.val().length > 0) {
+ enable_import_btn(true);
+ } else {
+ enable_import_btn(false);
+ }
+ }
+ if ($("#git-repo-radio").prop("checked")) {
+ if (vcsURLInput.val().length > 0 && gitRefInput.val().length > 0) {
+ enable_import_btn(true);
+ } else {
+ enable_import_btn(false);
+ }
+ }
+ });
+
+ localDirPath.on('input', function(){
+ if ($(this).val().trim().length == 0) {
+ $('#import-and-add-btn').attr("disabled","disabled");
+ $('#local-dir').addClass('has-error');
+ $('#hintError-dir-abs-path').show();
+ $('#hintError-dir-path-starts-with-slash').show();
+ } else {
+ var input = $(this);
+ var reBeginWithSlash = /^\//;
+ var reCheckVariable = /^\$/;
+ var re = /([ <>\\|":\.%\?\*]+)/;
+
+ var invalidDir = re.test(input.val());
+ var invalidSlash = reBeginWithSlash.test(input.val());
+ var invalidVar = reCheckVariable.test(input.val());
+
+ if (!invalidSlash && !invalidVar) {
+ $('#local-dir').addClass('has-error');
+ $('#import-and-add-btn').attr("disabled","disabled");
+ $('#hintError-dir-abs-path').show();
+ $('#hintError-dir-path-starts-with-slash').show();
+ } else if (invalidDir) {
+ $('#local-dir').addClass('has-error');
+ $('#import-and-add-btn').attr("disabled","disabled");
+ $('#hintError-dir-path').show();
+ } else {
+ $('#local-dir').removeClass('has-error');
+ if (layerNameInput.val().length > 0) {
+ $('#import-and-add-btn').removeAttr("disabled");
+ }
+ $('#hintError-dir-abs-path').hide();
+ $('#hintError-dir-path-starts-with-slash').hide();
+ $('#hintError-dir-path').hide();
+ }
+ }
+ });
}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/jsrender.min.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/jsrender.min.js
new file mode 100644
index 000000000..87cac4eb3
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/jsrender.min.js
@@ -0,0 +1,4 @@
+/*! JsRender v0.9.78 (Beta): http://jsviews.com/#jsrender */
+/*! **VERSION FOR WEB** (For NODE.JS see http://jsviews.com/download/jsrender-node.js) */
+!function(e,t){var n=t.jQuery;"object"==typeof exports?module.exports=n?e(t,n):function(n){if(n&&!n.fn)throw"Provide jQuery or null";return e(t,n)}:"function"==typeof define&&define.amd?define(function(){return e(t)}):e(t,!1)}(function(e,t){"use strict";function n(e,t){return function(){var n,r=this,i=r.base;return r.base=e,n=t.apply(r,arguments),r.base=i,n}}function r(e,t){return te(t)&&(t=n(e?e._d?e:n(s,e):s,t),t._d=1),t}function i(e,t){for(var n in t.props)Re.test(n)&&(e[n]=r(e[n],t.props[n]))}function o(e){return e}function s(){return""}function a(e){try{throw console.log("JsRender dbg breakpoint: "+e),"dbg breakpoint"}catch(t){}return this.base?this.baseApply(arguments):e}function d(e){this.name=(t.link?"JsViews":"JsRender")+" Error",this.message=e||this.name}function u(e,t){for(var n in t)e[n]=t[n];return e}function l(e,t,n){return e?(de.delimiters=[e,t,ve=n?n.charAt(0):ve],pe=e.charAt(0),ce=e.charAt(1),fe=t.charAt(0),ge=t.charAt(1),e="\\"+pe+"(\\"+ve+")?\\"+ce,t="\\"+fe+"\\"+ge,G="(?:(\\w+(?=[\\/\\s\\"+fe+"]))|(\\w+)?(:)|(>)|(\\*))\\s*((?:[^\\"+fe+"]|\\"+fe+"(?!\\"+ge+"))*?)",ae.rTag="(?:"+G+")",G=new RegExp("(?:"+e+G+"(\\/)?|\\"+pe+"(\\"+ve+")?\\"+ce+"(?:(?:\\/(\\w+))\\s*|!--[\\s\\S]*?--))"+t,"g"),W=new RegExp("<.*>|([^\\\\]|^)[{}]|"+e+".*"+t),le):de.delimiters}function p(e,t){t||e===!0||(t=e,e=void 0);var n,r,i,o,s=this,a=!t||"root"===t;if(e){if(o=t&&s.type===t&&s,!o)if(n=s.views,s._.useKey){for(r in n)if(o=t?n[r].get(e,t):n[r])break}else for(r=0,i=n.length;!o&&i>r;r++)o=t?n[r].get(e,t):n[r]}else if(a)for(;s.parent;)o=s,s=s.parent;else for(;s&&!o;)o=s.type===t?s:void 0,s=s.parent;return o}function c(){var e=this.get("item");return e?e.index:void 0}function f(){return this.index}function g(t){var n,r=this,i=r.linkCtx,o=(r.ctx||{})[t];return void 0===o&&i&&i.ctx&&(o=i.ctx[t]),void 0===o&&(o=oe[t]),o&&te(o)&&!o._wrp&&(n=function(){return o.apply(this&&this!==e?this:r,arguments)},n._wrp=r,u(n,o)),n||o}function v(e){return e&&(e.fn?e:this.getRsc("templates",e)||re(e))}function h(e,t,n,r){var o,s,a="number"==typeof n&&t.tmpl.bnds[n-1],d=t.linkCtx;return void 0!==r?n=r={props:{},args:[r]}:a&&(n=a(t.data,t,ae)),s=n.args[0],(e||a)&&(o=d&&d.tag,o||(o=u(new ae._tg,{_:{inline:!d,bnd:a,unlinked:!0},tagName:":",cvt:e,flow:!0,tagCtx:n}),d&&(d.tag=o,o.linkCtx=d),n.ctx=L(n.ctx,(d?d.view:t).ctx)),o._er=r&&s,i(o,n),n.view=t,o.ctx=n.ctx||o.ctx||{},n.ctx=void 0,s=o.cvtArgs("true"!==e&&e)[0],s=a&&t._.onRender?t._.onRender(s,t,o):s),void 0!=s?s:""}function m(e){var t=this,n=t.tagCtx,r=n.view,i=n.args;return e=e||t.convert,e=e&&(""+e===e?r.getRsc("converters",e)||S("Unknown converter: '"+e+"'"):e),i=i.length||n.index?e?i.slice():i:[r.data],e&&(e.depends&&(t.depends=ae.getDeps(t.depends,t,e.depends,e)),i[0]=e.apply(t,i)),i}function w(e,t){for(var n,r,i=this;void 0===n&&i;)r=i.tmpl&&i.tmpl[e],n=r&&r[t],i=i.parent;return n||Y[e][t]}function x(e,t,n,r,o,s){t=t||X;var a,d,u,l,p,c,f,g,v,h,m,w,x,b,_,y,k,j,C,A="",T=t.linkCtx||0,V=t.ctx,R=n||t.tmpl,M="number"==typeof r&&t.tmpl.bnds[r-1];for("tag"===e._is?(a=e,e=a.tagName,r=a.tagCtxs,u=a.template):(d=t.getRsc("tags",e)||S("Unknown tag: {{"+e+"}} "),u=d.template),void 0!==s?(A+=s,r=s=[{props:{},args:[]}]):M&&(r=M(t.data,t,ae)),g=r.length,f=0;g>f;f++)h=r[f],(!T||!T.tag||f&&!T.tag._.inline||a._er)&&((w=R.tmpls&&h.tmpl)&&(w=h.content=R.tmpls[w-1]),h.index=f,h.tmpl=w,h.render=N,h.view=t,h.ctx=L(h.ctx,V)),(n=h.props.tmpl)&&(h.tmpl=t.getTmpl(n)),a||(a=new d._ctr,x=!!a.init,a.parent=c=V&&V.tag,a.tagCtxs=r,C=a.dataMap,T&&(a._.inline=!1,T.tag=a,a.linkCtx=T),(a._.bnd=M||T.fn)?a._.arrVws={}:a.dataBoundOnly&&S("{^{"+e+"}} tag must be data-bound")),r=a.tagCtxs,C=a.dataMap,h.tag=a,C&&r&&(h.map=r[f].map),a.flow||(m=h.ctx=h.ctx||{},l=a.parents=m.parentTags=V&&L(m.parentTags,V.parentTags)||{},c&&(l[c.tagName]=c),l[a.tagName]=m.tag=a);if(!(a._er=s)){for(i(a,r[0]),a.rendering={},f=0;g>f;f++)h=a.tagCtx=r[f],k=h.props,y=a.cvtArgs(),(b=k.dataMap||C)&&(y.length||k.dataMap)&&(_=h.map,_&&_.src===y[0]&&!o||(_&&_.src&&_.unmap(),_=h.map=b.map(y[0],k,void 0,!a._.bnd)),y=[_.tgt]),a.ctx=h.ctx,f||(x&&(j=a.template,a.init(h,T,a.ctx),x=void 0),T&&(T.attr=a.attr=T.attr||a.attr),p=a.attr,a._.noVws=p&&p!==Ee),v=void 0,a.render&&(v=a.render.apply(a,y)),y.length||(y=[t]),void 0===v&&(v=h.render(y[0],!0)||(o?void 0:"")),A=A?A+(v||""):v;a.rendering=void 0}return a.tagCtx=r[0],a.ctx=a.tagCtx.ctx,a._.noVws&&a._.inline&&(A="text"===p?ie.html(A):""),M&&t._.onRender?t._.onRender(A,t,a):A}function b(e,t,n,r,i,o,s,a){var d,u,l,p=this,f="array"===t;p.content=a,p.views=f?[]:{},p.parent=n,p.type=t||"top",p.data=r,p.tmpl=i,l=p._={key:0,useKey:f?0:1,id:""+$e++,onRender:s,bnds:{}},p.linked=!!s,n?(d=n.views,u=n._,u.useKey?(d[l.key="_"+u.useKey++]=p,p.index=Ue,p.getIndex=c):d.length===(l.key=p.index=o)?d.push(p):d.splice(o,0,p),p.ctx=e||n.ctx):p.ctx=e}function _(e){var t,n,r,i,o,s,a;for(t in Oe)if(o=Oe[t],(s=o.compile)&&(n=e[t+"s"]))for(r in n)i=n[r]=s(r,n[r],e,0),i._is=t,i&&(a=ae.onStore[t])&&a(r,i,s)}function y(e,t,n){function i(){var t=this;t._={inline:!0,unlinked:!0},t.tagName=e}var o,s,a,d=new ae._tg;if(te(t)?t={depends:t.depends,render:t}:""+t===t&&(t={template:t}),s=t.baseTag){t.flow=!!t.flow,t.baseTag=s=""+s===s?n&&n.tags[s]||se[s]:s,d=u(d,s);for(a in t)d[a]=r(s[a],t[a])}else d=u(d,t);return void 0!==(o=d.template)&&(d.template=""+o===o?re[o]||re(o):o),d.init!==!1&&((i.prototype=d).constructor=d._ctr=i),n&&(d._parentTmpl=n),d}function k(e){return this.base.apply(this,e)}function j(e,n,r,i){function o(n){var o,a;if(""+n===n||n.nodeType>0&&(s=n)){if(!s)if(/^\.\/[^\\:*?"<>]*$/.test(n))(a=re[e=e||n])?n=a:s=document.getElementById(n);else if(t.fn&&!W.test(n))try{s=t(document).find(n)[0]}catch(d){}s&&(i?n=s.innerHTML:(o=s.getAttribute(Se),o?o!==Ie?(n=re[o],delete re[o]):t.fn&&(n=t.data(s)[Ie]):(e=e||(t.fn?Ie:n),n=j(e,s.innerHTML,r,i)),n.tmplName=e=e||o,e!==Ie&&(re[e]=n),s.setAttribute(Se,e),t.fn&&t.data(s,Ie,n))),s=void 0}else n.fn||(n=void 0);return n}var s,a,d=n=n||"";return 0===i&&(i=void 0,d=o(d)),i=i||(n.markup?n:{}),i.tmplName=e,r&&(i._parentTmpl=r),!d&&n.markup&&(d=o(n.markup))&&d.fn&&(d=d.markup),void 0!==d?(d.fn||n.fn?d.fn&&(a=d):(n=V(d,i),U(d.replace(ke,"\\$&"),n)),a||(_(i),a=u(function(){return n.render.apply(n,arguments)},n)),e&&!r&&e!==Ie&&(qe[e]=a),a):void 0}function C(e,n){return t.isFunction(e)?e.call(n):e}function A(e){var t,n=[],r=e.length;for(t=0;r>t;t++)n.push(e[t].unmap());return n}function T(e,n){function r(e){l.apply(this,e)}function i(){return new r(arguments)}function o(e,t){var n,r,i,o,s,a=c.length;for(n=0;a>n;n++)o=c[n],r=void 0,o+""!==o&&(r=o,o=r.getter),void 0===(s=e[o])&&r&&void 0!==(i=r.defaultVal)&&(s=C(i,e)),t(s,r&&p[r.type],o)}function s(n){n=n+""===n?JSON.parse(n):n;var r,i,s,u=n,l=[];if(t.isArray(n)){for(n=n||[],i=n.length,r=0;i>r;r++)l.push(this.map(n[r]));return l._is=e,l.unmap=d,l.merge=a,l}if(n){o(n,function(e,t){t&&(e=t.map(e)),l.push(e)}),u=this.apply(this,l);for(s in n)s===ee||b[s]||(u[s]=n[s])}return u}function a(e){e=e+""===e?JSON.parse(e):e;var n,r,s,a,d,u,l,p,c,f,v=this;if(t.isArray(v)){for(p={},f=[],s=e.length,a=v.length,n=0;s>n;n++){for(c=e[n],l=!1,r=0;a>r&&!l;r++)p[r]||(u=v[r],g&&(p[r]=l=g+""===g?c[g]&&(b[g]?u[g]():u[g])===c[g]:g(u,c)));l?(u.merge(c),f.push(u)):f.push(i.map(c))}return void(x?x(v).refresh(f,!0):v.splice.apply(v,[0,v.length].concat(f)))}o(e,function(e,t,n){t?v[n]().merge(e):v[n](e)});for(d in e)d===ee||b[d]||(v[d]=e[d])}function d(){var e,n,r,i,o,s,a=this;if(t.isArray(a))return A(a);for(e={},i=c.length,r=0;i>r;r++)n=c[r],o=void 0,n+""!==n&&(o=n,n=o.getter),s=a[n](),e[n]=o&&s&&p[o.type]?t.isArray(s)?A(s):s.unmap():s;for(n in a)"_is"===n||b[n]||n===ee||"_"===n.charAt(0)&&b[n.slice(1)]||t.isFunction(a[n])||(e[n]=a[n]);return e}var u,l,p=this,c=n.getters,f=n.extend,g=n.id,v=t.extend({_is:e||"unnamed",unmap:d,merge:a},f),h="",m="",w=c?c.length:0,x=t.observable,b={};for(r.prototype=v,u=0;w>u;u++)!function(e){e=e.getter||e,b[e]=u+1;var t="_"+e;h+=(h?",":"")+e,m+="this."+t+" = "+e+";\n",v[e]=v[e]||function(n){return arguments.length?void(x?x(this).setProperty(e,n):this[t]=n):this[t]},x&&(v[e].set=v[e].set||function(e){this[t]=e})}(c[u]);return l=new Function(h,m.slice(0,-1)),l.prototype=v,v.constructor=l,i.map=s,i.getters=c,i.extend=f,i.id=g,i}function V(e,n){var r,i=ue._wm||{},o=u({tmpls:[],links:{},bnds:[],_is:"template",render:N},n);return o.markup=e,n.htmlTag||(r=Ae.exec(e),o.htmlTag=r?r[1].toLowerCase():""),r=i[o.htmlTag],r&&r!==i.div&&(o.markup=t.trim(o.markup)),o}function R(e,t){function n(i,o,s){var a,d,u,l;if(i&&typeof i===Fe&&!i.nodeType&&!i.markup&&!i.getTgt&&!("viewModel"===e&&i.getters||i.extend)){for(u in i)n(u,i[u],o);return o||Y}return void 0===o&&(o=i,i=void 0),i&&""+i!==i&&(s=o,o=i,i=void 0),l=s?"viewModel"===e?s:s[r]=s[r]||{}:n,d=t.compile,null===o?i&&delete l[i]:(o=d?d.call(l,i,o,s,0):o,i&&(l[i]=o)),d&&o&&(o._is=e),o&&(a=ae.onStore[e])&&a(i,o,d),o}var r=e+"s";Y[r]=n}function M(e){le[e]=function(t){return arguments.length?(de[e]=t,le):de[e]}}function $(e){function t(t,n){this.tgt=e.getTgt(t,n)}return te(e)&&(e={getTgt:e}),e.baseMap&&(e=u(u({},e.baseMap),e)),e.map=function(e,n){return new t(e,n)},e}function N(e,t,n,r,i,o){var s,a,d,u,l,p,c,f,g=r,v="";if(t===!0?(n=t,t=void 0):typeof t!==Fe&&(t=void 0),(d=this.tag)?(l=this,g=g||l.view,u=g.getTmpl(d.template||l.tmpl),arguments.length||(e=g)):u=this,u){if(!g&&e&&"view"===e._is&&(g=e),g&&e===g&&(e=g.data),p=!g,me=me||p,g||((t=t||{}).root=e),!me||ue.useViews||u.useViews||g&&g!==X)v=E(u,e,t,n,g,i,o,d);else{if(g?(c=g.data,f=g.index,g.index=Ue):(g=X,g.data=e,g.ctx=t),ne(e)&&!n)for(s=0,a=e.length;a>s;s++)g.index=s,g.data=e[s],v+=u.fn(e[s],g,ae);else g.data=e,v+=u.fn(e,g,ae);g.data=c,g.index=f}p&&(me=void 0)}return v}function E(e,t,n,r,i,o,s,a){function d(e){_=u({},n),_[x]=e}var l,p,c,f,g,v,h,m,w,x,_,y,k="";if(a&&(w=a.tagName,y=a.tagCtx,n=n?L(n,a.ctx):a.ctx,e===i.content?h=e!==i.ctx._wrp?i.ctx._wrp:void 0:e!==y.content?e===a.template?(h=y.tmpl,n._wrp=y.content):h=y.content||i.content:h=i.content,y.props.link===!1&&(n=n||{},n.link=!1),(x=y.props.itemVar)&&("~"!==x.charAt(0)&&I("Use itemVar='~myItem'"),x=x.slice(1))),i&&(s=s||i._.onRender,n=L(n,i.ctx)),o===!0&&(v=!0,o=0),s&&(n&&n.link===!1||a&&a._.noVws)&&(s=void 0),m=s,s===!0&&(m=void 0,s=i._.onRender),n=e.helpers?L(e.helpers,n):n,_=n,ne(t)&&!r)for(c=v?i:void 0!==o&&i||new b(n,"array",i,t,e,o,s),i&&i._.useKey&&(c._.bnd=!a||a._.bnd&&a),x&&(c.it=x),x=c.it,l=0,p=t.length;p>l;l++)x&&d(t[l]),f=new b(_,"item",c,t[l],e,(o||0)+l,s,h),g=e.fn(t[l],f,ae),k+=c._.onRender?c._.onRender(g,f):g;else x&&d(t),c=v?i:new b(_,w||"data",i,t,e,o,s,h),a&&!a.flow&&(c.tag=a),k+=e.fn(t,c,ae);return m?m(k,c):k}function F(e,t,n){var r=void 0!==n?te(n)?n.call(t.data,e,t):n||"":"{Error: "+e.message+"}";return de.onError&&void 0!==(n=de.onError.call(t.data,e,n&&r,t))&&(r=n),t&&!t.linkCtx?ie.html(r):r}function S(e){throw new ae.Err(e)}function I(e){S("Syntax error\n"+e)}function U(e,t,n,r,i){function o(t){t-=v,t&&m.push(e.substr(v,t).replace(_e,"\\n"))}function s(t,n){t&&(t+="}}",I((n?"{{"+n+"}} block has {{/"+t+" without {{"+t:"Unmatched or missing {{/"+t)+", in template:\n"+e))}function a(a,d,u,c,g,x,b,_,y,k,j,C){(b&&d||y&&!u||_&&":"===_.slice(-1)||k)&&I(a),x&&(g=":",c=Ee),y=y||n&&!i;var A=(d||n)&&[[]],T="",V="",R="",M="",$="",N="",E="",F="",S=!y&&!g;u=u||(_=_||"#data",g),o(C),v=C+a.length,b?f&&m.push(["*","\n"+_.replace(/^:/,"ret+= ").replace(ye,"$1")+";\n"]):u?("else"===u&&(Ce.test(_)&&I('for "{{else if expr}}" use "{{else expr}}"'),A=w[7]&&[[]],w[8]=e.substring(w[8],C),w=h.pop(),m=w[2],S=!0),_&&O(_.replace(_e," "),A,t).replace(je,function(e,t,n,r,i,o,s,a){return r="'"+i+"':",s?(V+=o+",",M+="'"+a+"',"):n?(R+=r+o+",",N+=r+"'"+a+"',"):t?E+=o:("trigger"===i&&(F+=o),T+=r+o+",",$+=r+"'"+a+"',",p=p||Re.test(i)),""}).slice(0,-1),A&&A[0]&&A.pop(),l=[u,c||!!r||p||"",S&&[],J(M||(":"===u?"'#data',":""),$,N),J(V||(":"===u?"data,":""),T,R),E,F,A||0],m.push(l),S&&(h.push(w),w=l,w[8]=v)):j&&(s(j!==w[0]&&"else"!==w[0]&&j,w[0]),w[8]=e.substring(w[8],C),w=h.pop()),s(!w&&j),m=w[2]}var d,u,l,p,c,f=de.allowCode||t&&t.allowCode||le.allowCode===!0,g=[],v=0,h=[],m=g,w=[,,g];if(f&&(t.allowCode=f),n&&(void 0!==r&&(e=e.slice(0,-r.length-2)+ge),e=pe+e+ge),s(h[0]&&h[0][2].pop()[0]),e.replace(G,a),o(e.length),(v=g[g.length-1])&&s(""+v!==v&&+v[8]===v[8]&&v[0]),n){for(u=B(g,e,n),c=[],d=g.length;d--;)c.unshift(g[d][7]);q(u,c)}else u=B(g,t);return u}function q(e,t){var n,r,i=0,o=t.length;for(e.deps=[];o>i;i++){r=t[i];for(n in r)"_jsvto"!==n&&r[n].length&&(e.deps=e.deps.concat(r[n]))}e.paths=r}function J(e,t,n){return[e.slice(0,-1),t.slice(0,-1),n.slice(0,-1)]}function K(e,t){return"\n "+(t?t+":{":"")+"args:["+e[0]+"]"+(e[1]||!t?",\n props:{"+e[1]+"}":"")+(e[2]?",\n ctx:{"+e[2]+"}":"")}function O(e,t,n){function r(r,m,w,x,b,_,y,k,j,C,A,T,V,R,M,$,N,E,F,S){function q(e,n,r,s,a,d,p,c){var f="."===r;if(r&&(b=b.slice(n.length),/^\.?constructor$/.test(c||b)&&I(e),f||(e=(s?'view.hlp("'+s+'")':a?"view":"data")+(c?(d?"."+d:s?"":a?"":"."+r)+(p||""):(c=s?"":a?d||"":r,"")),e+=c?"."+c:"",e=n+("view.data"===e.slice(0,9)?e.slice(5):e)),u)){if(O="linkTo"===i?o=t._jsvto=t._jsvto||[]:l.bd,B=f&&O[O.length-1]){if(B._jsv){for(;B.sb;)B=B.sb;B.bnd&&(b="^"+b.slice(1)),B.sb=b,B.bnd=B.bnd||"^"===b.charAt(0)}}else O.push(b);h[g]=F+(f?1:0)}return e}x=u&&x,x&&!k&&(b=x+b),_=_||"",w=w||m||T,b=b||j,C=C||N||"";var J,K,O,B,L,Q=")";if("["===C&&(C="[j._sq(",Q=")]"),!y||d||a){if(u&&$&&!d&&!a&&(!i||s||o)&&(J=h[g-1],S.length-1>F-(J||0))){if(J=S.slice(J,F+r.length),K!==!0)if(O=o||p[g-1].bd,B=O[O.length-1],B&&B.prm){for(;B.sb&&B.sb.prm;)B=B.sb;L=B.sb={path:B.sb,bnd:B.bnd}}else O.push(L={path:O.pop()});$=ce+":"+J+" onerror=''"+fe,K=f[$],K||(f[$]=!0,f[$]=K=U($,n,!0)),K!==!0&&L&&(L._jsv=K,L.prm=l.bd,L.bnd=L.bnd||L.path&&L.path.indexOf("^")>=0)}return d?(d=!V,d?r:T+'"'):a?(a=!R,a?r:T+'"'):(w?(h[g]=F++,l=p[++g]={bd:[]},w):"")+(E?g?"":(c=S.slice(c,F),(i?(i=s=o=!1,"\b"):"\b,")+c+(c=F+r.length,u&&t.push(l.bd=[]),"\b")):k?(g&&I(e),u&&t.pop(),i=b,s=x,c=F+r.length,x&&(u=l.bd=t[i]=[]),b+":"):b?b.split("^").join(".").replace(xe,q)+(C?(l=p[++g]={bd:[]},v[g]=Q,C):_):_?_:M?(M=v[g]||M,v[g]=!1,l=p[--g],M+(C?(l=p[++g],v[g]=Q,C):"")):A?(v[g]||I(e),","):m?"":(d=V,a=R,'"'))}I(e)}var i,o,s,a,d,u=t&&t[0],l={bd:u},p={0:l},c=0,f=n?n.links:u&&(u.links=u.links||{}),g=0,v={},h={},m=(e+(n?" ":"")).replace(be,r);return!g&&m||I(e)}function B(e,t,n){var r,i,o,s,a,d,u,l,p,c,f,g,v,h,m,w,x,b,_,y,k,j,C,A,T,R,M,$,N,E,F=0,S=ue.useViews||t.useViews||t.tags||t.templates||t.helpers||t.converters,U="",J={},O=e.length;for(""+t===t?(b=n?'data-link="'+t.replace(_e," ").slice(1,-1)+'"':t,t=0):(b=t.tmplName||"unnamed",t.allowCode&&(J.allowCode=!0),t.debug&&(J.debug=!0),f=t.bnds,x=t.tmpls),r=0;O>r;r++)if(i=e[r],""+i===i)U+='\n+"'+i+'"';else if(o=i[0],"*"===o)U+=";\n"+i[1]+"\nret=ret";else{if(s=i[1],k=!n&&i[2],a=K(i[3],"params")+"},"+K(v=i[4]),$=i[5],E=i[6],j=i[8]&&i[8].replace(ye,"$1"),(T="else"===o)?g&&g.push(i[7]):(F=0,f&&(g=i[7])&&(g=[g],F=f.push(1))),S=S||v[1]||v[2]||g||/view.(?!index)/.test(v[0]),(R=":"===o)?s&&(o=s===Ee?">":s+o):(k&&(_=V(j,J),_.tmplName=b+"/"+o,_.useViews=_.useViews||S,B(k,_),S=_.useViews,x.push(_)),T||(y=o,S=S||o&&(!se[o]||!se[o].flow),A=U,U=""),C=e[r+1],C=C&&"else"===C[0]),N=$?";\ntry{\nret+=":"\n+",h="",m="",R&&(g||E||s&&s!==Ee)){if(M=new Function("data,view,j,u"," // "+b+" "+F+" "+o+"\nreturn {"+a+"};"),M._er=$,M._tag=o,n)return M;q(M,g),w='c("'+s+'",view,',c=!0,h=w+F+",",m=")"}if(U+=R?(n?($?"try{\n":"")+"return ":N)+(c?(c=void 0,S=p=!0,w+(g?(f[F-1]=M,F):"{"+a+"}")+")"):">"===o?(u=!0,"h("+v[0]+")"):(l=!0,"((v="+v[0]+")!=null?v:"+(n?"null)":'"")'))):(d=!0,"\n{view:view,tmpl:"+(k?x.length:"0")+","+a+"},"),y&&!C){if(U="["+U.slice(0,-1)+"]",w='t("'+y+'",view,this,',n||g){if(U=new Function("data,view,j,u"," // "+b+" "+F+" "+y+"\nreturn "+U+";"),U._er=$,U._tag=y,g&&q(f[F-1]=U,g),n)return U;h=w+F+",undefined,",m=")"}U=A+N+w+(F||U)+")",g=0,y=0}$&&(S=!0,U+=";\n}catch(e){ret"+(n?"urn ":"+=")+h+"j._err(e,view,"+$+")"+m+";}"+(n?"":"ret=ret"))}U="// "+b+"\nvar v"+(d?",t=j._tag":"")+(p?",c=j._cnvt":"")+(u?",h=j._html":"")+(n?";\n":',ret=""\n')+(J.debug?"debugger;":"")+U+(n?"\n":";\nreturn ret;"),de.debugMode!==!1&&(U="try {\n"+U+"\n}catch(e){\nreturn j._err(e, view);\n}");try{U=new Function("data,view,j,u",U)}catch(L){I("Compiled template code:\n\n"+U+'\n: "'+L.message+'"')}return t&&(t.fn=U,t.useViews=!!S),U}function L(e,t){return e&&e!==t?t?u(u({},t),e):e:t&&u({},t)}function Q(e){return Ne[e]||(Ne[e]="&#"+e.charCodeAt(0)+";")}function H(e){var t,n,r=[];if(typeof e===Fe)for(t in e)n=e[t],t===ee||te(n)||r.push({key:t,prop:n});return r}function P(e,n,r){var i=this.jquery&&(this[0]||S('Unknown template: "'+this.selector+'"')),o=i.getAttribute(Se);return N.call(o?t.data(i)[Ie]:re(i),e,n,r)}function D(e){return void 0!=e?Ve.test(e)&&(""+e).replace(Me,Q)||e:""}var Z=t===!1;t=t&&t.fn?t:e.jQuery;var z,G,W,X,Y,ee,te,ne,re,ie,oe,se,ae,de,ue,le,pe,ce,fe,ge,ve,he,me,we="v0.9.78",xe=/^(!*?)(?:null|true|false|\d[\d.]*|([\w$]+|\.|~([\w$]+)|#(view|([\w$]+))?)([\w$.^]*?)(?:[.[^]([\w$]+)\]?)?)$/g,be=/(\()(?=\s*\()|(?:([([])\s*)?(?:(\^?)(!*?[#~]?[\w$.^]+)?\s*((\+\+|--)|\+|-|&&|\|\||===|!==|==|!=|<=|>=|[<>%*:?\/]|(=))\s*|(!*?[#~]?[\w$.^]+)([([])?)|(,\s*)|(\(?)\\?(?:(')|("))|(?:\s*(([)\]])(?=\s*[.^]|\s*$|[^([])|[)\]])([([]?))|(\s+)/g,_e=/[ \t]*(\r\n|\n|\r)/g,ye=/\\(['"])/g,ke=/['"\\]/g,je=/(?:\x08|^)(onerror:)?(?:(~?)(([\w$_\.]+):)?([^\x08]+))\x08(,)?([^\x08]+)/gi,Ce=/^if\s/,Ae=/<(\w+)[>\s]/,Te=/[\x00`><"'&=]/g,Ve=/[\x00`><\"'&=]/,Re=/^on[A-Z]|^convert(Back)?$/,Me=Te,$e=0,Ne={"&":"&amp;","<":"&lt;",">":"&gt;","\x00":"&#0;","'":"&#39;",'"':"&#34;","`":"&#96;","=":"&#61;"},Ee="html",Fe="object",Se="data-jsv-tmpl",Ie="jsvTmpl",Ue="For #index in nested block use #getIndex().",qe={},Je=e.jsrender,Ke=Je&&t&&!t.render,Oe={template:{compile:j},tag:{compile:y},viewModel:{compile:T},helper:{},converter:{}};if(Y={jsviews:we,sub:{View:b,Err:d,tmplFn:U,parse:O,extend:u,extendCtx:L,syntaxErr:I,onStore:{},addSetting:M,settings:{allowCode:!1},advSet:s,_ths:i,_tg:function(){},_cnvt:h,_tag:x,_er:S,_err:F,_html:D,_sq:function(e){return"constructor"===e&&I(""),e}},settings:{delimiters:l,advanced:function(e){return e?(u(ue,e),ae.advSet(),le):ue}},map:$},(d.prototype=new Error).constructor=d,c.depends=function(){return[this.get("item"),"index"]},f.depends="index",b.prototype={get:p,getIndex:f,getRsc:w,getTmpl:v,hlp:g,_is:"view"},ae=Y.sub,le=Y.settings,!(Je||t&&t.render)){for(z in Oe)R(z,Oe[z]);ie=Y.converters,oe=Y.helpers,se=Y.tags,ae._tg.prototype={baseApply:k,cvtArgs:m},X=ae.topView=new b,t?(t.fn.render=P,ee=t.expando,t.observable&&(u(ae,t.views.sub),Y.map=t.views.map)):(t={},Z&&(e.jsrender=t),t.renderFile=t.__express=t.compile=function(){throw"Node.js: use npm jsrender, or jsrender-node.js"},t.isFunction=function(e){return"function"==typeof e},t.isArray=Array.isArray||function(e){return"[object Array]"==={}.toString.call(e)},ae._jq=function(e){e!==t&&(u(e,t),t=e,t.fn.render=P,delete t.jsrender,ee=t.expando)},t.jsrender=we),de=ae.settings,de.allowCode=!1,te=t.isFunction,ne=t.isArray,t.render=qe,t.views=Y,t.templates=re=Y.templates;for(he in de)M(he);(le.debugMode=function(e){return void 0===e?de.debugMode:(de.debugMode=e,de.onError=e+""===e?new Function("","return '"+e+"';"):te(e)?e:void 0,le)})(!1),ue=de.advanced={useViews:!1,_jsv:!1},se({"if":{render:function(e){var t=this,n=t.tagCtx,r=t.rendering.done||!e&&(arguments.length||!n.index)?"":(t.rendering.done=!0,t.selected=n.index,n.render(n.view,!0));return r},flow:!0},"for":{render:function(e){var t,n=!arguments.length,r=this,i=r.tagCtx,o="",s=0;return r.rendering.done||(t=n?i.view.data:e,void 0!==t&&(o+=i.render(t,n),s+=ne(t)?t.length:1),(r.rendering.done=s)&&(r.selected=i.index)),o},flow:!0},props:{baseTag:"for",dataMap:$(H),flow:!0},include:{flow:!0},"*":{render:o,flow:!0},":*":{render:o,flow:!0},dbg:oe.dbg=ie.dbg=a}),ie({html:D,attr:D,url:function(e){return void 0!=e?encodeURI(""+e):null===e?e:""}})}return de=ae.settings,le.delimiters("{{","}}","^"),Ke&&Je.views.sub._jq(t),t||Je},window);
+//# sourceMappingURL=jsrender.min.js.map
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerBtn.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerBtn.js
index 259271df3..9f9eda1e1 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerBtn.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerBtn.js
@@ -55,8 +55,8 @@ function layerBtnsInit() {
});
});
- $(".build-recipe-btn").unbind('click');
- $(".build-recipe-btn").click(function(e){
+ $("td .build-recipe-btn").unbind('click');
+ $("td .build-recipe-btn").click(function(e){
e.preventDefault();
var recipe = $(this).data('recipe-name');
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js
index 825f9dccd..e9622243a 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerDepsModal.js
@@ -6,7 +6,12 @@
* addToProject: Whether to add layers to project on accept
* successAdd: function to run on success
*/
-function showLayerDepsModal(layer, dependencies, title, body, addToProject, successAdd) {
+function showLayerDepsModal(layer,
+ dependencies,
+ title,
+ body,
+ addToProject,
+ successAdd) {
if ($("#dependencies-modal").length === 0) {
$.get(libtoaster.ctx.htmlUrl + "/layer_deps_modal.html", function(html){
@@ -33,17 +38,20 @@ function showLayerDepsModal(layer, dependencies, title, body, addToProject, succ
var deplistHtml = "";
for (var i = 0; i < dependencies.length; i++) {
- deplistHtml += "<li><label class=\"checkbox\"><input name=\"dependencies\" value=\"";
+ deplistHtml += "<li><div class=\"checkbox\"><label><input name=\"dependencies\" value=\"";
deplistHtml += dependencies[i].id;
deplistHtml +="\" type=\"checkbox\" checked=\"checked\"/>";
deplistHtml += dependencies[i].name;
- deplistHtml += "</label></li>";
+ deplistHtml += "</label></div></li>";
}
$('#dependencies-list').html(deplistHtml);
$("#dependencies-modal").data("deps", dependencies);
- $('#dependencies-modal').modal('show');
+ /* Clear any alert notifications before showing the modal */
+ $(".alert").fadeOut(function(){
+ $('#dependencies-modal').modal('show');
+ });
/* Discard the old submission function */
$("#dependencies-modal-form").unbind('submit');
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerdetails.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerdetails.js
index d54540626..9ead393cb 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerdetails.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/layerdetails.js
@@ -10,25 +10,27 @@ function layerDetailsPageInit (ctx) {
var targetTab = $("#targets-tab");
var machineTab = $("#machines-tab");
var detailsTab = $("#details-tab");
+ var editLayerSource = $("#edit-layer-source");
+ var saveSourceChangesBtn = $("#save-changes-for-switch");
+ var layerGitRefInput = $("#layer-git-ref");
+ var layerSubDirInput = $('#layer-subdir');
+
+ targetTab.on('show.bs.tab', targetsTabShow);
+ detailsTab.on('show.bs.tab', detailsTabShow);
+ machineTab.on('show.bs.tab', machinesTabShow);
/* setup the dependencies typeahead */
- libtoaster.makeTypeahead(layerDepInput, libtoaster.ctx.layersTypeAheadUrl, { include_added: "true" }, function(item){
+ libtoaster.makeTypeahead(layerDepInput,
+ libtoaster.ctx.layersTypeAheadUrl,
+ { include_added: "true" }, function(item){
currentLayerDepSelection = item;
-
layerDepBtn.removeAttr("disabled");
});
- $(window).on('hashchange', function(e){
- switch(window.location.hash){
- case '#machines':
- machineTab.tab('show');
- break;
- case '#recipes':
- targetTab.tab('show');
- break;
- default:
- detailsTab.tab('show');
- break;
+ /* disable the add layer button if its input field is empty */
+ layerDepInput.on("keyup",function(){
+ if ($(this).val().length === 0) {
+ layerDepBtn.attr("disabled", "disabled");
}
});
@@ -76,7 +78,7 @@ function layerDetailsPageInit (ctx) {
addRemoveDep(currentLayerDepSelection.id, true, function(){
/* Make a list item for the new layer dependency */
- var newLayerDep = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Delete\"></span></li>");
+ var newLayerDep = $("<li><a></a><span class=\"glyphicon glyphicon-trash\" data-toggle=\"tooltip\" title=\"Delete\"></span></li>");
newLayerDep.data('layer-id', currentLayerDepSelection.id);
newLayerDep.children("span").tooltip();
@@ -94,11 +96,11 @@ function layerDetailsPageInit (ctx) {
/* Clear the current selection */
layerDepInput.val("");
currentLayerDepSelection = undefined;
- layerDepBtn.attr("disabled","disabled");
+ layerDepBtn.attr("disabled", "disabled");
});
});
- $(".icon-pencil").click(function (){
+ $(".glyphicon-edit").click(function (){
var mParent = $(this).parent("dd");
mParent.prev().css("margin-top", "10px");
mParent.children("form").slideDown();
@@ -106,8 +108,12 @@ function layerDetailsPageInit (ctx) {
currentVal.hide();
/* Set the current value to the input field */
mParent.find("textarea,input").val(currentVal.text());
+ /* If the input field is empty, disable the submit button */
+ if ( mParent.find("textarea,input").val().length == 0 ) {
+ mParent.find(".change-btn").attr("disabled", "disabled");
+ }
/* Hides the "Not set" text */
- mParent.children(".muted").hide();
+ mParent.children(".text-muted").hide();
/* We're editing so hide the delete icon */
mParent.children(".delete-current-value").hide();
mParent.find(".cancel").show();
@@ -128,30 +134,31 @@ function layerDetailsPageInit (ctx) {
mParent.children(".current-value").show();
/* Show the "Not set" text if we ended up with no value */
if (!mParent.children(".current-value").html()){
- mParent.children(".muted").fadeIn();
+ mParent.children(".text-muted").fadeIn();
mParent.children(".delete-current-value").hide();
} else {
mParent.children(".delete-current-value").show();
}
- mParent.children(".icon-pencil").show();
- mParent.prev().css("margin-top", "0px");
+ mParent.children(".glyphicon-edit").show();
+ mParent.prev().css("margin-top", "0");
});
});
+
function defaultAddBtnText(){
var text = " Add the "+ctx.layerVersion.name+" layer to your project";
addRmLayerBtn.text(text);
- addRmLayerBtn.prepend("<span class=\"icon-plus\"></span>");
+ addRmLayerBtn.prepend("<span class=\"glyphicon glyphicon-plus\"></span>");
addRmLayerBtn.removeClass("btn-danger");
}
- detailsTab.on('show', function(){
+ function detailsTabShow(){
if (!ctx.layerVersion.inCurrentPrj)
defaultAddBtnText();
- window.location.hash = "details";
- });
+ window.location.hash = "information";
+ }
function targetsTabShow(){
if (!ctx.layerVersion.inCurrentPrj){
@@ -159,7 +166,7 @@ function layerDetailsPageInit (ctx) {
var text = " Add the "+ctx.layerVersion.name+" layer to your project "+
"to enable these recipes";
addRmLayerBtn.text(text);
- addRmLayerBtn.prepend("<span class=\"icon-plus\"></span>");
+ addRmLayerBtn.prepend("<span class=\"glyphicon glyphicon-plus\"></span>");
} else {
defaultAddBtnText();
}
@@ -177,7 +184,7 @@ function layerDetailsPageInit (ctx) {
$("#no-recipes-yet").hide();
}
- targetTab.removeClass("muted");
+ targetTab.removeClass("text-muted");
if (window.location.hash === "#recipes"){
/* re run the machinesTabShow to update the text */
targetsTabShow();
@@ -192,20 +199,19 @@ function layerDetailsPageInit (ctx) {
else
$("#no-machines-yet").hide();
- machineTab.removeClass("muted");
+ machineTab.removeClass("text-muted");
if (window.location.hash === "#machines"){
/* re run the machinesTabShow to update the text */
machinesTabShow();
}
$(".select-machine-btn").click(function(e){
- if ($(this).attr("disabled") === "disabled")
+ if ($(this).hasClass("disabled"))
e.preventDefault();
});
});
- targetTab.on('show', targetsTabShow);
function machinesTabShow(){
if (!ctx.layerVersion.inCurrentPrj) {
@@ -213,7 +219,7 @@ function layerDetailsPageInit (ctx) {
var text = " Add the "+ctx.layerVersion.name+" layer to your project " +
"to enable these machines";
addRmLayerBtn.text(text);
- addRmLayerBtn.prepend("<span class=\"icon-plus\"></span>");
+ addRmLayerBtn.prepend("<span class=\"glyphicon glyphicon-plus\"></span>");
} else {
defaultAddBtnText();
}
@@ -222,8 +228,6 @@ function layerDetailsPageInit (ctx) {
window.location.hash = "machines";
}
- machineTab.on('show', machinesTabShow);
-
$(".pagesize").change(function(){
var search = libtoaster.parseUrlParams();
search.limit = this.value;
@@ -239,17 +243,17 @@ function layerDetailsPageInit (ctx) {
if (added){
/* enable and switch all the button states */
- $(".build-recipe-btn").removeAttr("disabled");
- $(".select-machine-btn").removeAttr("disabled");
+ $(".build-recipe-btn").removeClass("disabled");
+ $(".select-machine-btn").removeClass("disabled");
addRmLayerBtn.addClass("btn-danger");
addRmLayerBtn.data('directive', "remove");
addRmLayerBtn.text(" Remove the "+ctx.layerVersion.name+" layer from your project");
- addRmLayerBtn.prepend("<span class=\"icon-trash\"></span>");
+ addRmLayerBtn.prepend("<span class=\"glyphicon glyphicon-trash\"></span>");
} else {
/* disable and switch all the button states */
- $(".build-recipe-btn").attr("disabled","disabled");
- $(".select-machine-btn").attr("disabled", "disabled");
+ $(".build-recipe-btn").addClass("disabled");
+ $(".select-machine-btn").addClass("disabled");
addRmLayerBtn.removeClass("btn-danger");
addRmLayerBtn.data('directive', "add");
@@ -257,7 +261,7 @@ function layerDetailsPageInit (ctx) {
* on which tab is currently visible. Unfortunately we can't just call
* tab('show') as if it's already visible it doesn't run the event.
*/
- switch ($(".nav-pills .active a").prop('id')){
+ switch ($(".nav-tabs .active a").prop('id')){
case 'machines-tab':
machinesTabShow();
break;
@@ -286,7 +290,7 @@ function layerDetailsPageInit (ctx) {
setLayerInCurrentPrj(add);
- $("#alert-area").show();
+ libtoaster.showChangeNotification(alertMsg);
});
});
@@ -325,7 +329,7 @@ function layerDetailsPageInit (ctx) {
text = entryElement.val();
/* Hide the "Not set" text if it's visible */
- inputArea.find(".muted").hide();
+ inputArea.find(".text-muted").hide();
inputArea.find(".current-value").text(text);
/* Same behaviour as cancel in that we hide the form/show current
* value.
@@ -343,9 +347,9 @@ function layerDetailsPageInit (ctx) {
/* Disable the change button when we have no data in the input */
$("dl input, dl textarea").on("input",function() {
if ($(this).val().length === 0)
- $(this).parent().children(".change-btn").attr("disabled", "disabled");
+ $(this).parent().next(".change-btn").attr("disabled", "disabled");
else
- $(this).parent().children(".change-btn").removeAttr("disabled");
+ $(this).parent().next(".change-btn").removeAttr("disabled");
});
/* This checks to see if the dt's dd has data in it or if the change data
@@ -355,11 +359,11 @@ function layerDetailsPageInit (ctx) {
if ($(this).is("dt")) {
var dd = $(this).next("dd");
if (!dd.children("form:visible")|| !dd.find(".current-value").html()){
- if (ctx.layerVersion.sourceId == 3){
+ if (ctx.layerVersion.layer_source == ctx.layerSourceTypes.TYPE_IMPORTED){
/* There's no current value and the layer is editable
* so show the "Not set" and hide the delete icon
*/
- dd.find(".muted").show();
+ dd.find(".text-muted").show();
dd.find(".delete-current-value").hide();
} else {
/* We're not viewing an editable layer so hide the empty dd/dl pair */
@@ -386,10 +390,132 @@ function layerDetailsPageInit (ctx) {
$(this).parents("form").submit();
});
+ $("#layer-delete-confirmed").click(function(){
+
+ $("#delete-layer-modal button[data-dismiss='modal']").hide();
+
+ var message = $('<span>You have deleted <strong>1</strong> layer from your project: <strong id="deleted-layer-name"></strong>');
+ message.find("#deleted-layer-name").text(ctx.layerVersion.name);
- layerDepsList.find(".icon-trash").click(layerDepRemoveClick);
+ $.ajax({
+ type: "DELETE",
+ url: ctx.xhrUpdateLayerUrl,
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function(data) {
+ if (data.error != "ok") {
+ console.warn(data.error);
+ } else {
+ libtoaster.setNotification("layer-deleted", message.html());
+ window.location.replace(data.gotoUrl);
+ }
+ },
+ error: function(data) {
+ console.warn("Call failed");
+ console.warn(data);
+ }
+ });
+ });
+
+ layerDepsList.find(".glyphicon-trash").click(layerDepRemoveClick);
layerDepsList.find("a").tooltip();
- $(".icon-trash").tooltip();
+ $(".glyphicon-trash").tooltip();
$(".commit").tooltip();
+ editLayerSource.click(function() {
+ /* Kindly bring the git layers imported from layerindex to normal page
+ * and not this new page :(
+ */
+ $(this).hide();
+ saveSourceChangesBtn.attr("disabled", "disabled");
+
+ $("#git-repo-info, #directory-info").hide();
+ $("#edit-layer-source-form").fadeIn();
+ if ($("#layer-dir-path-in-details").val() == "") {
+ //Local dir path is empty...
+ $("#repo").prop("checked", true);
+ $("#layer-git").fadeIn();
+ $("#layer-dir").hide();
+ } else {
+ $("#layer-git").hide();
+ $("#layer-dir").fadeIn();
+ }
+ });
+
+ $('input:radio[name="source-location"]').change(function() {
+ if ($('input[name=source-location]:checked').val() == "repo") {
+ $("#layer-git").fadeIn();
+ $("#layer-dir").hide();
+ if ($("#layer-git-repo-url").val().length === 0 && layerGitRefInput.val().length === 0) {
+ saveSourceChangesBtn.attr("disabled", "disabled");
+ }
+ } else {
+ $("#layer-dir").fadeIn();
+ $("#layer-git").hide();
+ }
+ });
+
+ $("#layer-dir-path-in-details").keyup(function() {
+ saveSourceChangesBtn.removeAttr("disabled");
+ });
+
+ $("#layer-git-repo-url").keyup(function() {
+ if ($("#layer-git-repo-url").val().length > 0 && layerGitRefInput.val().length > 0) {
+ saveSourceChangesBtn.removeAttr("disabled");
+ }
+ });
+
+ layerGitRefInput.keyup(function() {
+ if ($("#layer-git-repo-url").val().length > 0 && layerGitRefInput.val().length > 0) {
+ saveSourceChangesBtn.removeAttr("disabled");
+ }
+ });
+
+
+ layerSubDirInput.keyup(function(){
+ if ($(this).val().length > 0){
+ saveSourceChangesBtn.removeAttr("disabled");
+ }
+ });
+
+ $('#cancel-changes-for-switch').click(function() {
+ $("#edit-layer-source-form").hide();
+ $("#directory-info, #git-repo-info").fadeIn();
+ editLayerSource.show();
+ });
+
+ saveSourceChangesBtn.click(function() {
+
+ var layerData = {
+ vcs_url: $('#layer-git-repo-url').val(),
+ commit: layerGitRefInput.val(),
+ dirpath: layerSubDirInput.val(),
+ local_source_dir: $('#layer-dir-path-in-details').val(),
+ };
+
+ if ($('input[name=source-location]:checked').val() == "repo") {
+ layerData.local_source_dir = "";
+ } else {
+ layerData.vcs_url = "";
+ layerData.git_ref = "";
+ }
+
+ $.ajax({
+ type: "POST",
+ url: ctx.xhrUpdateLayerUrl,
+ data: layerData,
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function (data) {
+ if (data.error != "ok") {
+ console.warn(data.error);
+ } else {
+ /* success layer property changed */
+ window.location.reload();
+ }
+ },
+ error: function (data) {
+ console.warn("Call failed");
+ console.warn(data);
+ }
+ });
+ });
}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
index 43930a2c3..86662b7a6 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
@@ -3,96 +3,82 @@
* This object really just helps readability since we can then have
* a traceable namespace.
*/
-var libtoaster = (function (){
-
- /* makeTypeahead parameters
- * elementSelector: JQuery elementSelector string
- * xhrUrl: the url to get the JSON from expects JSON in the form:
- * { "list": [ { "name": "test", "detail" : "a test thing" }, .... ] }
+var libtoaster = (function () {
+ // prevent conflicts with Bootstrap 2's typeahead (required during
+ // transition from v2 to v3)
+ var typeahead = jQuery.fn.typeahead.noConflict();
+ jQuery.fn._typeahead = typeahead;
+
+ /* Make a typeahead from an input element
+ *
+ * _makeTypeahead parameters
+ * jQElement: input element as selected by $('selector')
+ * xhrUrl: the url to get the JSON from; this URL should return JSON in the
+ * format:
+ * { "results": [ { "name": "test", "detail" : "a test thing" }, ... ] }
* xhrParams: the data/parameters to pass to the getJSON url e.g.
- * { 'type' : 'projects' } the text typed will be passed as 'search'.
- * selectedCB: function to call once an item has been selected one
- * arg of the item.
+ * { 'type' : 'projects' }; the text typed will be passed as 'search'.
+ * selectedCB: function to call once an item has been selected; has
+ * signature selectedCB(item), where item is an item in the format shown
+ * in the JSON list above, i.e.
+ * { "name": "name", "detail": "detail" }.
*/
- function _makeTypeahead (jQElement, xhrUrl, xhrParams, selectedCB) {
- if (!xhrUrl || xhrUrl.length === 0)
- throw("No url to typeahead supplied");
+ function _makeTypeahead(jQElement, xhrUrl, xhrParams, selectedCB) {
+ if (!xhrUrl || xhrUrl.length === 0) {
+ throw("No url supplied for typeahead");
+ }
var xhrReq;
- jQElement.typeahead({
- // each time the typeahead's choices change, a
- // "typeahead-choices-change" event is fired with an object
- // containing the available choices in a "choices" property
- source: function(query, process){
+ jQElement._typeahead(
+ {
+ highlight: true,
+ classNames: {
+ open: "dropdown-menu",
+ cursor: "active"
+ }
+ },
+ {
+ source: function (query, syncResults, asyncResults) {
xhrParams.search = query;
- /* If we have a request in progress don't fire off another one*/
- if (xhrReq)
+ // if we have a request in progress, cancel it and start another
+ if (xhrReq) {
xhrReq.abort();
+ }
- xhrReq = $.getJSON(xhrUrl, this.options.xhrParams, function(data){
+ xhrReq = $.getJSON(xhrUrl, xhrParams, function (data) {
if (data.error !== "ok") {
- console.log("Error getting data from server "+data.error);
+ console.error("Error getting data from server: " + data.error);
return;
}
xhrReq = null;
- jQElement.trigger("typeahead-choices-change", {choices: data.results});
-
- return process(data.results);
+ asyncResults(data.results);
});
},
- updater: function(item) {
- var itemObj = this.$menu.find('.active').data('itemObject');
- selectedCB(itemObj);
- return item;
- },
- matcher: function(item) {
- if (!item.hasOwnProperty('name')) {
- console.log("Name property missing in data");
- return 0;
- }
-
- if (this.$element.val().length === 0)
- return 0;
- return 1;
- },
- highlighter: function (item) {
- /* Use jquery to escape the item name and detail */
- var current = $("<span></span>").text(item.name + ' '+item.detail);
- current = current.html();
-
- var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
- return current.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
- return '<strong>' + match + '</strong>'
- })
+ // how the selected item is shown in the input
+ display: function (item) {
+ return item.name;
},
- sorter: function (items) { return items; },
- xhrUrl: xhrUrl,
- xhrParams: xhrParams,
- xhrReq: xhrReq,
- });
-
-
- /* Copy of bootstrap's render func but sets selectedObject value */
- function customRenderFunc (items) {
- var that = this;
- items = $(items).map(function (i, item) {
- i = $(that.options.item).attr('data-value', item.name).data('itemObject', item);
- i.find('a').html(that.highlighter(item));
- return i[0];
- });
-
- items.first().addClass('active');
- this.$menu.html(items);
- return this;
- }
+ templates: {
+ // how the item is displayed in the dropdown
+ suggestion: function (item) {
+ var elt = document.createElement("div");
+ elt.innerHTML = item.name + " " + item.detail;
+ return elt;
+ }
+ }
+ }
+ );
- jQElement.data('typeahead').render = customRenderFunc;
+ // when an item is selected using the typeahead, invoke the callback
+ jQElement.on("typeahead:select", function (event, item) {
+ selectedCB(item);
+ });
}
/* startABuild:
@@ -162,11 +148,25 @@ var libtoaster = (function (){
});
}
+ function _getMostRecentBuilds(url, onsuccess, onfail) {
+ $.ajax({
+ url: url,
+ type: 'GET',
+ data : {format: 'json'},
+ headers: {'X-CSRFToken': $.cookie('csrftoken')},
+ success: function (data) {
+ onsuccess ? onsuccess(data) : console.log(data);
+ },
+ error: function (data) {
+ onfail ? onfail(data) : console.error(data);
+ }
+ });
+ }
+
/* Get a project's configuration info */
function _getProjectInfo(url, onsuccess, onfail){
$.ajax({
type: "GET",
- data : { format: "json" },
url: url,
headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
success: function (_data) {
@@ -193,7 +193,7 @@ var libtoaster = (function (){
function _editCurrentProject(data, onSuccess, onFail){
$.ajax({
type: "POST",
- url: libtoaster.ctx.projectPageUrl + "?format=json",
+ url: libtoaster.ctx.xhrProjectUrl,
data: data,
headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
success: function (data) {
@@ -314,11 +314,11 @@ var libtoaster = (function (){
var alertMsg;
if (layerDepsList.length > 0 && add === true) {
- alertMsg = $("<span>You have added <strong>"+(layerDepsList.length+1)+"</strong> layers to your project: <a id=\"layer-affected-name\"></a> and its dependencies </span>");
+ alertMsg = $("<span>You have added <strong>"+(layerDepsList.length+1)+"</strong> layers to your project: <a class=\"alert-link\" id=\"layer-affected-name\"></a> and its dependencies </span>");
/* Build the layer deps list */
layerDepsList.map(function(layer, i){
- var link = $("<a></a>");
+ var link = $("<a class=\"alert-link\"></a>");
link.attr("href", layer.layerdetailurl);
link.text(layer.name);
@@ -330,9 +330,9 @@ var libtoaster = (function (){
alertMsg.append(link);
});
} else if (layerDepsList.length === 0 && add === true) {
- alertMsg = $("<span>You have added <strong>1</strong> layer to your project: <a id=\"layer-affected-name\"></a></span></span>");
+ alertMsg = $("<span>You have added <strong>1</strong> layer to your project: <a class=\"alert-link\" id=\"layer-affected-name\"></a></span></span>");
} else if (add === false) {
- alertMsg = $("<span>You have removed <strong>1</strong> layer from your project: <a id=\"layer-affected-name\"></a></span>");
+ alertMsg = $("<span>You have removed <strong>1</strong> layer from your project: <a class=\"alert-link\" id=\"layer-affected-name\"></a></span>");
}
alertMsg.children("#layer-affected-name").text(layer.name);
@@ -342,10 +342,12 @@ var libtoaster = (function (){
}
function _showChangeNotification(message){
- var alertMsg = $("#change-notification-msg");
+ $(".alert-dismissible").fadeOut().promise().done(function(){
+ var alertMsg = $("#change-notification-msg");
- alertMsg.html(message);
- $("#change-notification, #change-notification *").fadeIn();
+ alertMsg.html(message);
+ $("#change-notification, #change-notification *").fadeIn();
+ });
}
function _createCustomRecipe(name, baseRecipeId, doneCb){
@@ -374,11 +376,98 @@ var libtoaster = (function (){
});
}
+ /* Validate project names. Use unique project names
+
+ All arguments accepted by this function are JQeury objects.
+
+ For example if the HTML element has "hint-error-project-name", then
+ it is passed to this function as $("#hint-error-project-name").
+
+ Arg1 - projectName : This is a string object. In the HTML, project name will be entered here.
+ Arg2 - hintEerror : This is a jquery object which will accept span which throws error for
+ duplicate project
+ Arg3 - ctrlGrpValidateProjectName : This object holds the div with class "control-group"
+ Arg4 - enableOrDisableBtn : This object will help the API to enable or disable the form.
+ For example in the new project the create project button will be hidden if the
+ duplicate project exist. Similarly in the projecttopbar the save button will be
+ disabled if the project name already exist.
+
+ Return - This function doesn't return anything. It sets/unsets the behavior of the elements.
+ */
+
+ function _makeProjectNameValidation(projectName, hintError,
+ ctrlGrpValidateProjectName, enableOrDisableBtn ) {
+
+ function checkProjectName(projectName){
+ $.ajax({
+ type: "GET",
+ url: libtoaster.ctx.projectsTypeAheadUrl,
+ data: { 'search' : projectName },
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function(data){
+ if (data.results.length > 0 &&
+ data.results[0].name === projectName) {
+ // This project name exists hence show the error and disable
+ // the save button
+ ctrlGrpValidateProjectName.addClass('has-error');
+ hintError.show();
+ enableOrDisableBtn.attr('disabled', 'disabled');
+ } else {
+ ctrlGrpValidateProjectName.removeClass('has-error');
+ hintError.hide();
+ enableOrDisableBtn.removeAttr('disabled');
+ }
+ },
+ error: function (data) {
+ console.log(data);
+ },
+ });
+ }
+
+ /* The moment user types project name remove the error */
+ projectName.on("input", function() {
+ var projectName = $(this).val();
+ checkProjectName(projectName)
+ });
+
+ /* Validate new project name */
+ projectName.on("blur", function(){
+ var projectName = $(this).val();
+ checkProjectName(projectName)
+ });
+ }
+
+ // if true, the loading spinner for Ajax requests will be displayed
+ // if requests take more than 1200ms
+ var ajaxLoadingTimerEnabled = true;
+
+ // turn on the page-level loading spinner for Ajax requests
+ function _enableAjaxLoadingTimer() {
+ ajaxLoadingTimerEnabled = true;
+ }
+
+ // turn off the page-level loading spinner for Ajax requests
+ function _disableAjaxLoadingTimer() {
+ ajaxLoadingTimerEnabled = false;
+ }
+
+ /* Utility function to set a notification for the next page load */
+ function _setNotification(name, message){
+ var data = {
+ name: name,
+ message: message
+ };
+
+ $.cookie('toaster-notification', JSON.stringify(data), { path: '/'});
+ }
return {
+ enableAjaxLoadingTimer: _enableAjaxLoadingTimer,
+ disableAjaxLoadingTimer: _disableAjaxLoadingTimer,
reload_params : reload_params,
startABuild : _startABuild,
cancelABuild : _cancelABuild,
+ getMostRecentBuilds: _getMostRecentBuilds,
makeTypeahead : _makeTypeahead,
getProjectInfo: _getProjectInfo,
getLayerDepsForProject : _getLayerDepsForProject,
@@ -390,6 +479,8 @@ var libtoaster = (function (){
makeLayerAddRmAlertMsg : _makeLayerAddRmAlertMsg,
showChangeNotification : _showChangeNotification,
createCustomRecipe: _createCustomRecipe,
+ makeProjectNameValidation: _makeProjectNameValidation,
+ setNotification: _setNotification,
};
})();
@@ -421,10 +512,24 @@ function reload_params(params) {
window.location.href = url+"?"+callparams.join('&');
}
-
/* Things that happen for all pages */
$(document).ready(function() {
+ (function showNotificationRequest(){
+ var cookie = $.cookie('toaster-notification');
+
+ if (!cookie)
+ return;
+
+ var notificationData = JSON.parse(cookie);
+
+ libtoaster.showChangeNotification(notificationData.message);
+
+ $.removeCookie('toaster-notification', { path: "/"});
+ })();
+
+
+
var ajaxLoadingTimer;
/* If we don't have a console object which might be the case in some
@@ -493,9 +598,7 @@ $(document).ready(function() {
delay: { show : 300 }
});
- // show help bubble only on hover inside tables
- $(".hover-help").css("visibility","hidden");
-
+ // show help bubble on hover inside tables
$("table").on("mouseover", "th, td", function () {
$(this).find(".hover-help").css("visibility","visible");
});
@@ -509,14 +612,14 @@ $(document).ready(function() {
// show task type and outcome in task details pages
$(".task-info").tooltip({ container: 'body', html: true, delay: {show: 200}, placement: 'right' });
- // initialise the tooltips for the icon-pencil icons
- $(".icon-pencil").tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Change" });
+ // initialise the tooltips for the edit icons
+ $(".glyphicon-edit").tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Change" });
// initialise the tooltips for the download icons
$(".icon-download-alt").tooltip({ container: 'body', html: true, delay: { show: 200 } });
// initialise popover for debug information
- $(".icon-info-sign").popover( { placement: 'bottom', html: true, container: 'body' });
+ $(".glyphicon-info-sign").popover( { placement: 'bottom', html: true, container: 'body' });
// linking directly to tabs
$(function(){
@@ -582,7 +685,9 @@ $(document).ready(function() {
window.clearTimeout(ajaxLoadingTimer);
ajaxLoadingTimer = window.setTimeout(function() {
- $("#loading-notification").fadeIn();
+ if (libtoaster.ajaxLoadingTimerEnabled) {
+ $("#loading-notification").fadeIn();
+ }
}, 1200);
});
@@ -613,6 +718,11 @@ $(document).ready(function() {
});
}
+ /* Make sure we don't have a notification overlay a modal */
+ $(".modal").on('show.bs.modal', function(){
+ $(".alert-dismissible").fadeOut();
+ });
+
if (libtoaster.debug) {
check_for_duplicate_ids();
} else {
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/mrbsection.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/mrbsection.js
index 09117e1da..73d0935fa 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/mrbsection.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/mrbsection.js
@@ -1,33 +1,19 @@
function mrbSectionInit(ctx){
-
- var projectBuilds;
-
- if (ctx.mrbType === 'project')
- projectBuilds = true;
-
- $(".cancel-build-btn").click(function(e){
+ $('#latest-builds').on('click', '.cancel-build-btn', function(e){
+ e.stopImmediatePropagation();
e.preventDefault();
var url = $(this).data('request-url');
var buildReqIds = $(this).data('buildrequest-id');
- var banner = $(this).parents(".alert");
-
- banner.find(".progress-info").fadeOut().promise().done(function(){
- $("#cancelling-msg-" + buildReqIds).show();
- console.log("cancel build");
- libtoaster.cancelABuild(url, buildReqIds, function(){
- if (projectBuilds == false){
- /* the all builds page is not 'self updating' like thei
- * project Builds
- */
- window.location.reload();
- }
- }, null);
- });
+
+ libtoaster.cancelABuild(url, buildReqIds, function () {
+ window.location.reload();
+ }, null);
});
- $(".run-again-btn").click(function(e){
+ $('#latest-builds').on('click', '.rebuild-btn', function(e){
+ e.stopImmediatePropagation();
e.preventDefault();
var url = $(this).data('request-url');
@@ -38,58 +24,112 @@ function mrbSectionInit(ctx){
}, null);
});
+ // cached version of buildData, so we can determine whether a build has
+ // changed since it was last fetched, and update the DOM appropriately
+ var buildData = {};
- var progressTimer;
-
- if (projectBuilds === true){
- progressTimer = window.setInterval(function() {
- libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,
- function(prjInfo){
- /* These two are needed because a build can be 100% and still
- * in progress due to the fact that the % done is updated at the
- * start of a task so it can be doing the last task at 100%
- */
- var inProgress = 0;
- var allPercentDone = 0;
- if (prjInfo.builds.length === 0)
- return
-
- for (var i in prjInfo.builds){
- var build = prjInfo.builds[i];
-
- if (build.outcome === "In Progress" ||
- $(".progress .bar").length > 0){
- /* Update the build progress */
- var percentDone;
-
- if (build.outcome !== "In Progress"){
- /* We have to ignore the value when it's Succeeded because it
- * goes back to 0
- */
- percentDone = 100;
- } else {
- percentDone = build.percentDone;
- inProgress++;
- }
-
- $("#build-pc-done-" + build.id).text(percentDone);
- $("#build-pc-done-title-" + build.id).attr("title", percentDone);
- $("#build-pc-done-bar-" + build.id).css("width",
- String(percentDone) + "%");
-
- allPercentDone += percentDone;
- }
- }
+ // returns the cached version of this build, or {} is there isn't a cached one
+ function getCached(build) {
+ return buildData[build.id] || {};
+ }
+
+ // returns true if a build's state changed to "Succeeded", "Failed"
+ // or "Cancelled" from some other value
+ function buildFinished(build) {
+ var cached = getCached(build);
+ return cached.state &&
+ cached.state !== build.state &&
+ (build.state == 'Succeeded' || build.state == 'Failed' ||
+ build.state == 'Cancelled');
+ }
+
+ // returns true if the state changed
+ function stateChanged(build) {
+ var cached = getCached(build);
+ return (cached.state !== build.state);
+ }
+
+ // returns true if the tasks_complete_percentage changed
+ function tasksProgressChanged(build) {
+ var cached = getCached(build);
+ return (cached.tasks_complete_percentage !== build.tasks_complete_percentage);
+ }
- if (allPercentDone === (100 * prjInfo.builds.length) && !inProgress)
+ // returns true if the number of recipes parsed/to parse changed
+ function recipeProgressChanged(build) {
+ var cached = getCached(build);
+ return (cached.recipes_parsed_percentage !== build.recipes_parsed_percentage);
+ }
+
+ function refreshMostRecentBuilds(){
+ libtoaster.getMostRecentBuilds(
+ libtoaster.ctx.mostRecentBuildsUrl,
+
+ // success callback
+ function (data) {
+ var build;
+ var tmpl;
+ var container;
+ var selector;
+ var colourClass;
+ var elements;
+
+ for (var i = 0; i < data.length; i++) {
+ build = data[i];
+
+ if (buildFinished(build)) {
+ // a build finished: reload the whole page so that the build
+ // shows up in the builds table
window.location.reload();
+ }
+ else if (stateChanged(build)) {
+ // update the whole template
+ build.warnings_pluralise = (build.warnings !== 1 ? 's' : '');
+ build.errors_pluralise = (build.errors !== 1 ? 's' : '');
+
+ tmpl = $.templates("#build-template");
+
+ html = $(tmpl.render(build));
+
+ selector = '[data-latest-build-result="' + build.id + '"] ' +
+ '[data-role="build-status-container"]';
+ container = $(selector);
+
+ // initialize bootstrap tooltips in the new HTML
+ html.find('span.glyphicon-question-sign').tooltip();
- /* Our progress bar is not still showing so shutdown the polling. */
- if ($(".progress .bar").length === 0)
- window.clearInterval(progressTimer);
+ container.html(html);
+ }
+ else if (tasksProgressChanged(build)) {
+ // update the task progress text
+ selector = '#build-pc-done-' + build.id;
+ $(selector).html(build.tasks_complete_percentage);
+
+ // update the task progress bar
+ selector = '#build-pc-done-bar-' + build.id;
+ $(selector).width(build.tasks_complete_percentage + '%');
+ }
+ else if (recipeProgressChanged(build)) {
+ // update the recipe progress text
+ selector = '#recipes-parsed-percentage-' + build.id;
+ $(selector).html(build.recipes_parsed_percentage);
+
+ // update the recipe progress bar
+ selector = '#recipes-parsed-percentage-bar-' + build.id;
+ $(selector).width(build.recipes_parsed_percentage + '%');
+ }
- });
- }, 1500);
+ buildData[build.id] = build;
+ }
+ },
+
+ // fail callback
+ function (data) {
+ console.error(data);
+ }
+ );
}
-}
+ window.setInterval(refreshMostRecentBuilds, 1500);
+ refreshMostRecentBuilds();
+}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
index cb9ed4da0..dace8e325 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
@@ -22,26 +22,40 @@ function newCustomImageModalInit(){
var nameInput = imgCustomModal.find('input');
var invalidNameMsg = "Image names cannot contain spaces or capital letters. The only allowed special character is dash (-).";
- var duplicateNameMsg = "A recipe with this name already exists. Image names must be unique.";
+ var duplicateNameMsg = "An image with this name already exists. Image names must be unique.";
var duplicateImageInProjectMsg = "An image with this name already exists in this project."
var invalidBaseRecipeIdMsg = "Please select an image to customise.";
- // capture clicks on radio buttons inside the modal; when one is selected,
- // set the recipe on the modal
- imgCustomModal.on("click", "[name='select-image']", function (e) {
+ // set button to "submit" state and enable text entry so user can
+ // enter the custom recipe name
+ showSubmitState();
+
+ /* capture clicks on radio buttons inside the modal; when one is selected,
+ * set the recipe on the modal
+ */
+ imgCustomModal.on("click", "[name='select-image']", function(e) {
clearRecipeError();
+ $(".radio").each(function(){
+ $(this).removeClass("has-error");
+ });
var recipeId = $(e.target).attr('data-recipe');
imgCustomModal.data('recipe', recipeId);
});
newCustomImgBtn.click(function(e){
+ // disable the button and text entry
+ showLoadingState();
+
e.preventDefault();
var baseRecipeId = imgCustomModal.data('recipe');
if (!baseRecipeId) {
showRecipeError(invalidBaseRecipeIdMsg);
+ $(".radio").each(function(){
+ $(this).addClass("has-error");
+ });
return;
}
@@ -62,16 +76,37 @@ function newCustomImageModalInit(){
}
} else {
imgCustomModal.modal('hide');
+ imgCustomModal.one('hidden.bs.modal', showSubmitState);
window.location.replace(ret.url + '?notify=new');
}
});
}
});
+ // enable text entry, show "Create image" button text
+ function showSubmitState() {
+ libtoaster.enableAjaxLoadingTimer();
+ newCustomImgBtn.find('[data-role="loading-state"]').hide();
+ newCustomImgBtn.find('[data-role="submit-state"]').show();
+ newCustomImgBtn.removeAttr('disabled');
+ nameInput.removeAttr('disabled');
+ }
+
+ // disable text entry, show "Creating image..." button text;
+ // we also disabled the page-level ajax loading spinner while this spinner
+ // is active
+ function showLoadingState() {
+ libtoaster.disableAjaxLoadingTimer();
+ newCustomImgBtn.find('[data-role="submit-state"]').hide();
+ newCustomImgBtn.find('[data-role="loading-state"]').show();
+ newCustomImgBtn.attr('disabled', 'disabled');
+ nameInput.attr('disabled', 'disabled');
+ }
+
function showNameError(text){
invalidNameHelp.text(text);
invalidNameHelp.show();
- nameInput.parent().addClass('error');
+ nameInput.parent().addClass('has-error');
}
function showRecipeError(text){
@@ -92,26 +127,26 @@ function newCustomImageModalInit(){
if (nameInput.val().search(/[^a-z|0-9|-]/) != -1){
showNameError(invalidNameMsg);
newCustomImgBtn.prop("disabled", true);
- nameInput.parent().addClass('error');
+ nameInput.parent().addClass('has-error');
} else {
invalidNameHelp.hide();
newCustomImgBtn.prop("disabled", false);
- nameInput.parent().removeClass('error');
+ nameInput.parent().removeClass('has-error');
}
});
}
-// Set the image recipes which can used as the basis for the custom
-// image recipe the user is creating
-//
-// baseRecipes: a list of one or more recipes which can be
-// used as the base for the new custom image recipe in the format:
-// [{'id': <recipe ID>, 'name': <recipe name>'}, ...]
-//
-// if recipes is a single recipe, just show the text box to set the
-// name for the new custom image; if recipes contains multiple recipe objects,
-// show a set of radio buttons so the user can decide which to use as the
-// basis for the new custom image
+/* Set the image recipes which can used as the basis for the custom
+ * image recipe the user is creating
+ * baseRecipes: a list of one or more recipes which can be
+ * used as the base for the new custom image recipe in the format:
+ * [{'id': <recipe ID>, 'name': <recipe name>'}, ...]
+ *
+ * if recipes is a single recipe, just show the text box to set the
+ * name for the new custom image; if recipes contains multiple recipe objects,
+ * show a set of radio buttons so the user can decide which to use as the
+ * basis for the new custom image
+ */
function newCustomImageModalSetRecipes(baseRecipes) {
var imgCustomModal = $("#new-custom-image-modal");
var imageSelector = $('#new-custom-image-modal [data-role="image-selector"]');
@@ -124,8 +159,9 @@ function newCustomImageModalSetRecipes(baseRecipes) {
// hide the radio button container
imageSelector.hide();
- // set the single recipe ID on the modal as it's the only one
- // we can build from
+ /* set the single recipe ID on the modal as it's the only one
+ * we can build from.
+ */
imgCustomModal.data('recipe', baseRecipes[0].id);
}
else {
@@ -134,14 +170,29 @@ function newCustomImageModalSetRecipes(baseRecipes) {
for (var i = 0; i < baseRecipes.length; i++) {
var recipe = baseRecipes[i];
imageSelectRadiosContainer.append(
- '<label class="radio" data-role="image-radio">' +
- recipe.name +
- '<input type="radio" class="form-control" name="select-image" ' +
+ '<div class="radio"><label data-role="image-radio">' +
+ '<input type="radio" name="select-image" ' +
'data-recipe="' + recipe.id + '">' +
- '</label>'
+ recipe.name +
+ '</label></div>'
);
}
+ /* select the first radio button as default selection. Radio button
+ * groups should always display with an option checked
+ */
+ imageSelectRadiosContainer.find("input:radio:first").attr("checked", "checked");
+
+ /* check which radio button is selected by default inside the modal,
+ * and set the recipe on the modal accordingly
+ */
+ imageSelectRadiosContainer.find("input:radio").each(function(){
+ if ( $(this).is(":checked") ) {
+ var recipeId = $(this).attr("data-recipe");
+ imgCustomModal.data("recipe", recipeId);
+ }
+ });
+
// show the radio button container
imageSelector.show();
}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projectpage.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projectpage.js
index 3013416dd..453670364 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projectpage.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projectpage.js
@@ -27,11 +27,10 @@ function projectPageInit(ctx) {
var urlParams = libtoaster.parseUrlParams();
- libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl, function(prjInfo){
+ libtoaster.getProjectInfo(libtoaster.ctx.xhrProjectUrl, function(prjInfo){
updateProjectLayers(prjInfo.layers);
updateFreqBuildRecipes(prjInfo.freqtargets);
updateProjectRelease(prjInfo.release);
- updateProjectReleases(prjInfo.releases, prjInfo.release);
/* If we're receiving a machine set from the url and it's different from
* our current machine then activate set machine sequence.
@@ -46,54 +45,13 @@ function projectPageInit(ctx) {
/* Now we're really ready show the page */
$("#project-page").show();
- });
-
- (function notificationRequest(){
-
- if (urlParams.hasOwnProperty('notify')){
- switch (urlParams.notify){
- case 'new-project':
- $("#project-created-notification").show();
- break;
- case 'layer-imported':
- layerImportedNotification();
- break;
- default:
- break;
- }
- }
- })();
-
- /* Layer imported notification */
- function layerImportedNotification(){
- var imported = $.cookie("layer-imported-alert");
- var message = "Layer imported";
-
- if (!imported)
- return;
- else
- imported = JSON.parse(imported);
-
- if (imported.deps_added.length === 0) {
- message = "You have imported <strong><a href=\""+imported.imported_layer.layerdetailurl+"\">"+imported.imported_layer.name+"</a></strong> and added it to your project.";
- } else {
- var links = "<a href=\""+imported.imported_layer.layerdetailurl+"\">"+imported.imported_layer.name+"</a>, ";
-
- imported.deps_added.map (function(item, index){
- links +='<a href="'+item.layerdetailurl+'">'+item.name+'</a>';
- /*If we're at the last element we don't want the trailing comma */
- if (imported.deps_added[index+1] !== undefined)
- links += ', ';
- });
-
- /* Length + 1 here to do deps + the imported layer */
- message = 'You have imported <strong><a href="'+imported.imported_layer.layerdetailurl+'">'+imported.imported_layer.name+'</a></strong> and added <strong>'+(imported.deps_added.length+1)+'</strong> layers to your project: <strong>'+links+'</strong>';
- }
-
- libtoaster.showChangeNotification(message);
+ /* Set the project name in the delete modal */
+ $("#delete-project-modal .project-name").text(prjInfo.name);
+ });
- $.removeCookie("layer-imported-alert", { path: "/"});
+ if (urlParams.hasOwnProperty('notify') && urlParams.notify === 'new-project'){
+ $("#project-created-notification").show();
}
/* Add/Rm layer functionality */
@@ -145,7 +103,7 @@ function projectPageInit(ctx) {
for (var i in layers){
var layerObj = layers[i];
- var projectLayer = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Remove\"></span></li>");
+ var projectLayer = $("<li><a></a><span class=\"glyphicon glyphicon-trash\" data-toggle=\"tooltip\" title=\"Remove\"></span></li>");
projectLayer.data('layer', layerObj);
projectLayer.children("span").tooltip();
@@ -154,7 +112,12 @@ function projectPageInit(ctx) {
link.attr("href", layerObj.layerdetailurl);
link.text(layerObj.name);
- link.tooltip({title: layerObj.vcs_url + " | "+ layerObj.vcs_reference, placement: "right"});
+
+ if (layerObj.local_source_dir) {
+ link.tooltip({title: layerObj.local_source_dir, placement: "right"});
+ } else {
+ link.tooltip({title: layerObj.vcs_url + " | "+ layerObj.vcs_reference, placement: "right"});
+ }
var trashItem = projectLayer.children("span");
trashItem.click(function (e) {
@@ -208,7 +171,7 @@ function projectPageInit(ctx) {
}
for (var i in recipes){
- var freqTargetCheck = $('<li><label class="checkbox"><input type="checkbox" /><span class="freq-target-name"></span></label></li>');
+ var freqTargetCheck = $('<li><div class="checkbox"><label><input type="checkbox" /><span class="freq-target-name"></span></label></li>');
freqTargetCheck.find(".freq-target-name").text(recipes[i]);
freqTargetCheck.find("input").val(recipes[i]);
freqTargetCheck.click(function(){
@@ -264,7 +227,9 @@ function projectPageInit(ctx) {
machineNameTitle.text(machineName);
}
- libtoaster.makeTypeahead(machineChangeInput, libtoaster.ctx.machinesTypeAheadUrl, { }, function(item){
+ libtoaster.makeTypeahead(machineChangeInput,
+ libtoaster.ctx.machinesTypeAheadUrl,
+ { }, function(item){
currentMachineAddSelection = item.name;
machineChangeBtn.removeAttr("disabled");
});
@@ -285,7 +250,7 @@ function projectPageInit(ctx) {
machineChangeCancel.click();
/* Show the alert message */
- var message = $('<span class="lead">You have changed the machine to: <strong><span id="notify-machine-name"></span></strong></span>');
+ var message = $('<span>You have changed the machine to: <strong><span id="notify-machine-name"></span></strong></span>');
message.find("#notify-machine-name").text(currentMachineAddSelection);
libtoaster.showChangeNotification(message);
},
@@ -301,146 +266,35 @@ function projectPageInit(ctx) {
releaseTitle.text(release.description);
}
- function updateProjectReleases(releases, current){
- for (var i in releases){
- var releaseOption = $("<option></option>");
- releaseOption.val(releases[i].id);
- releaseOption.text(releases[i].description);
- releaseOption.data('release', releases[i]);
-
- if (releases[i].id == current.id)
- releaseOption.attr("selected", "selected");
-
- releaseForm.children("select").append(releaseOption);
- }
- }
-
- releaseChangeFormToggle.click(function(){
- releaseForm.slideDown();
- releaseTitle.hide();
- $(this).hide();
- });
-
- cancelReleaseChange.click(function(e){
+ $("#delete-project-confirmed").click(function(e){
e.preventDefault();
- releaseForm.slideUp(function(){
- releaseTitle.show();
- releaseChangeFormToggle.show();
- });
- });
-
- function changeProjectRelease(release, layersToRm){
- libtoaster.editCurrentProject({ projectVersion : release.id },
- function(){
- /* Success */
- /* Update layers list with new layers */
- layersInPrjList.addClass('muted');
- libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,
- function(prjInfo){
- layersInPrjList.children().remove();
- updateProjectLayers(prjInfo.layers);
- layersInPrjList.removeClass('muted');
- releaseChangedNotification(release, prjInfo.layers, layersToRm);
- });
- updateProjectRelease(release);
- cancelReleaseChange.click();
- });
- }
-
- /* Create a notification to show the changes to the layer configuration
- * caused by changing a release.
- */
-
- function releaseChangedNotification(release, layers, layersToRm){
-
- var message;
-
- if (layers.length === 0 && layersToRm.length === 0){
- message = $('<span><span class="lead">You have changed the project release to: <strong><span id="notify-release-name"></span></strong>.');
- message.find("#notify-release-name").text(release.description);
- libtoaster.showChangeNotification(message);
- return;
- }
-
- /* Create the whitespace separated list of layers removed */
- var layersDelList = "";
-
- layersToRm.map(function(layer, i){
- layersDelList += layer.name;
- if (layersToRm[i+1] !== undefined)
- layersDelList += ', ';
- });
-
- message = $('<span><span class="lead">You have changed the project release to: <strong><span id="notify-release-name"></span></strong>. This has caused the following changes in your project layers:</span><ul id="notify-layers-changed-list"></ul></span>');
-
- var changedList = message.find("#notify-layers-changed-list");
-
- message.find("#notify-release-name").text(release.description);
-
- /* Manually construct the list item for changed layers */
- var li = '<li><strong>'+layers.length+'</strong> layers changed to the <strong>'+release.name+'</strong> release: ';
- for (var i in layers){
- li += '<a href='+layers[i].layerdetailurl+'>'+layers[i].name+'</a>';
- if (i !== 0)
- li += ', ';
- }
-
- changedList.append($(li));
-
- /* Layers removed */
- if (layersToRm && layersToRm.length > 0){
- if (layersToRm.length == 1)
- li = '<li><strong>1</strong> layer removed: '+layersToRm[0].name+'</li>';
- else
- li = '<li><strong>'+layersToRm.length+'</strong> layers deleted: '+layersDelList+'</li>';
-
- changedList.append($(li));
- }
-
- libtoaster.showChangeNotification(message);
- }
-
- /* Show the modal dialog which gives the option to remove layers which
- * aren't compatible with the proposed release
- */
- function showReleaseLayerChangeModal(release, layers){
- var layersToRmList = releaseModal.find("#layers-to-remove-list");
- layersToRmList.text("");
-
- releaseModal.find(".proposed-release-change-name").text(release.description);
- releaseModal.data("layers", layers);
- releaseModal.data("release", release);
-
- for (var i in layers){
- layersToRmList.append($("<li></li>").text(layers[i].name));
- }
- releaseModal.modal('show');
- }
-
- $("#change-release-btn").click(function(e){
- e.preventDefault();
-
- var newRelease = releaseForm.find("option:selected").data('release');
-
- $.getJSON(ctx.testReleaseChangeUrl,
- { new_release_id: newRelease.id },
- function(layers) {
- if (layers.rows.length === 0){
- /* No layers to change for this release */
- changeProjectRelease(newRelease, []);
- } else {
- showReleaseLayerChangeModal(newRelease, layers.rows);
+ libtoaster.disableAjaxLoadingTimer();
+ $(this).find('[data-role="submit-state"]').hide();
+ $(this).find('[data-role="loading-state"]').show();
+ $(this).attr("disabled", "disabled");
+ $('#delete-project-modal [data-dismiss="modal"]').hide();
+
+ $.ajax({
+ type: 'DELETE',
+ url: libtoaster.ctx.xhrProjectUrl,
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function (data) {
+ if (data.error !== "ok") {
+ console.warn(data.error);
+ } else {
+ var msg = $('<span>You have deleted <strong>1</strong> project: <strong id="project-deleted"></strong></span>');
+
+ msg.find("#project-deleted").text(libtoaster.ctx.projectName);
+ libtoaster.setNotification("project-deleted", msg.html());
+
+ window.location.replace(data.gotoUrl);
+ }
+ },
+ error: function (data) {
+ console.warn(data);
}
});
});
- /* Release change modal accept */
- $("#change-release-and-rm-layers").click(function(){
- var layers = releaseModal.data("layers");
- var release = releaseModal.data("release");
-
- changeProjectRelease(release, layers);
- });
-
}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projecttopbar.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projecttopbar.js
index b09f974e4..92ab2d67f 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projecttopbar.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/projecttopbar.js
@@ -4,7 +4,7 @@ function projectTopBarInit(ctx) {
var projectNameForm = $("#project-name-change-form");
var projectNameContainer = $("#project-name-container");
- var projectName = $("#project-name");
+ var projectName = $(".project-name");
var projectNameFormToggle = $("#project-change-form-toggle");
var projectNameChangeCancel = $("#project-name-change-cancel");
@@ -25,13 +25,14 @@ function projectTopBarInit(ctx) {
e.preventDefault();
projectNameForm.hide();
projectNameContainer.fadeIn();
+ $("#project-name-change-input").val(projectName.first().text());
});
$("#project-name-change-btn").click(function(){
var newProjectName = $("#project-name-change-input").val();
libtoaster.editCurrentProject({ projectName: newProjectName }, function (){
- projectName.html(newProjectName);
+ projectName.text(newProjectName);
libtoaster.ctx.projectName = newProjectName;
projectNameChangeCancel.click();
});
@@ -87,4 +88,10 @@ function projectTopBarInit(ctx) {
window.location.replace(libtoaster.ctx.projectBuildsUrl);
}, null);
});
+
+ /* Call makeProjectNameValidation function */
+ libtoaster.makeProjectNameValidation($("#project-name-change-input"),
+ $("#hint-error-project-name"), $("#validate-project-name"),
+ $("#project-name-change-btn"));
+
}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/table.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/table.js
index f738144ae..176ce579f 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/table.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/table.js
@@ -15,6 +15,7 @@ function tableInit(ctx){
orderby : null,
filter : null,
search : null,
+ default_orderby: null,
};
var defaultHiddenCols = [];
@@ -75,14 +76,21 @@ function tableInit(ctx){
if (tableData.total === 0){
tableContainer.hide();
- if ($("#no-results-special-"+ctx.tableName).length > 0) {
- /* use this page's special no-results form instead of the default */
- $("#no-results-search-input-"+ctx.tableName).val(tableParams.search);
- $("#no-results-special-"+ctx.tableName).show();
- $("#results-found-"+ctx.tableName).hide();
- } else {
- $("#new-search-input-"+ctx.tableName).val(tableParams.search);
- $("#no-results-"+ctx.tableName).show();
+ /* No results caused by a search returning nothing */
+ if (tableParams.search) {
+ if ($("#no-results-special-"+ctx.tableName).length > 0) {
+ /* use this page's special no-results form instead of the default */
+ $("#no-results-search-input-"+ctx.tableName).val(tableParams.search);
+ $("#no-results-special-"+ctx.tableName).show();
+ $("#results-found-"+ctx.tableName).hide();
+ } else {
+ $("#new-search-input-"+ctx.tableName).val(tableParams.search);
+ $("#no-results-"+ctx.tableName).show();
+ }
+ }
+ else {
+ /* No results caused by there being no data */
+ $("#empty-state-"+ctx.tableName).show();
}
table.trigger("table-done", [tableData.total, tableParams]);
@@ -90,6 +98,7 @@ function tableInit(ctx){
} else {
tableContainer.show();
$("#no-results-"+ctx.tableName).hide();
+ $("#empty-state-"+ctx.tableName).hide();
}
setupTableChrome(tableData);
@@ -101,27 +110,8 @@ function tableInit(ctx){
var row = $("<tr></tr>");
column_index = -1;
for (var key_j in tableData.rows[i]){
-
- /* if we have a static: version of a key, prefer the static: version for rendering */
- var orig_key_j = key_j;
-
- if (key_j.indexOf("static:") === 0) {
- if (key_j.substr("static:".length) in tableData.rows[i]) {
- continue;
- }
- orig_key_j = key_j.substr("static:".length)
- } else if (("static:" + key_j) in tableData.rows[i]) {
- key_j = "static:" + key_j;
- }
-
- /* we skip over un-displayable column entries */
- column_index += 1;
- if (! tableData.columns[column_index].displayable) {
- continue;
- }
-
var td = $("<td></td>");
- td.prop("class", orig_key_j);
+ td.prop("class", key_j);
if (tableData.rows[i][key_j]){
td.html(tableData.rows[i][key_j]);
}
@@ -181,6 +171,15 @@ function tableInit(ctx){
table.css("padding-bottom", 0);
tableContainer.css("visibility", "visible");
+ /* If we have a hash in the url try and highlight that item in the table */
+ if (window.location.hash){
+ var highlight = $("table a[name="+window.location.hash.replace('#',''));
+ if (highlight.length > 0){
+ highlight.parents("tr").addClass('highlight');
+ window.scroll(0, highlight.position().top - 50);
+ }
+ }
+
table.trigger("table-done", [tableData.total, tableParams]);
}
@@ -188,12 +187,14 @@ function tableInit(ctx){
if (tableChromeDone === true)
return;
- var tableHeadRow = table.find("thead");
+ var tableHeadRow = table.find("thead > tr");
var editColMenu = $("#table-chrome-"+ctx.tableName).find(".editcol");
tableHeadRow.html("");
editColMenu.html("");
+ tableParams.default_orderby = tableData.default_orderby;
+
if (!tableParams.orderby && tableData.default_orderby){
tableParams.orderby = tableData.default_orderby;
}
@@ -209,7 +210,7 @@ function tableInit(ctx){
/* Setup the help text */
if (col.help_text.length > 0) {
- var help_text = $('<i class="icon-question-sign get-help"> </i>');
+ var help_text = $('<span class="glyphicon glyphicon-question-sign get-help"> </span>');
help_text.tooltip({title: col.help_text});
header.append(help_text);
}
@@ -219,6 +220,7 @@ function tableInit(ctx){
var title = $('<a href=\"#\" ></a>');
title.data('field-name', col.field_name);
+ title.attr('data-sort-field', col.field_name);
title.text(col.title);
title.click(sortColumnClicked);
@@ -246,12 +248,12 @@ function tableInit(ctx){
} else {
/* Not orderable */
header.css("font-weight", "normal");
- header.append('<span class="muted">' + col.title + '</span> ');
+ header.append('<span class="text-muted">' + col.title + '</span> ');
}
/* Setup the filter button */
if (col.filter_name){
- var filterBtn = $('<a href="#" role="button" data-filter-on="' + col.filter_name + '" class="pull-right btn btn-mini" data-toggle="modal"><i class="icon-filter filtered"></i></a>');
+ var filterBtn = $('<a href="#" role="button" data-filter-on="' + col.filter_name + '" class="pull-right btn btn-link btn-xs" data-toggle="modal"><i class="glyphicon glyphicon-filter filtered"></i></a>');
filterBtn.data('filter-name', col.filter_name);
filterBtn.prop('id', col.filter_name);
@@ -270,7 +272,7 @@ function tableInit(ctx){
tableHeadRow.append(header);
/* Now setup the checkbox state and click handler */
- var toggler = $('<li><label class="checkbox">'+col.title+'<input type="checkbox" id="checkbox-'+ col.field_name +'" class="col-toggle" value="'+col.field_name+'" /></label></li>');
+ var toggler = $('<li><div class="checkbox"><label><input type="checkbox" id="checkbox-'+ col.field_name +'" class="col-toggle" value="'+col.field_name+'" />'+col.title+'</label></div></li>');
var togglerInput = toggler.find("input");
@@ -280,7 +282,8 @@ function tableInit(ctx){
if (col.hideable){
togglerInput.click(colToggleClicked);
} else {
- toggler.find("label").addClass("muted");
+ toggler.find("label").addClass("text-muted");
+ toggler.find("label").parent().addClass("disabled");
togglerInput.attr("disabled", "disabled");
}
@@ -297,11 +300,12 @@ function tableInit(ctx){
/* Toggles the active state of the filter button */
function filterBtnActive(filterBtn, active){
if (active) {
+ filterBtn.removeClass("btn-link");
filterBtn.addClass("btn-primary");
filterBtn.tooltip({
html: true,
- title: '<button class="btn btn-small btn-primary" onClick=\'$("#clear-filter-btn-'+ ctx.tableName +'").click();\'>Clear filter</button>',
+ title: '<button class="btn btn-sm btn-primary" onClick=\'$("#clear-filter-btn-'+ ctx.tableName +'").click();\'>Clear filter</button>',
placement: 'bottom',
delay: {
hide: 1500,
@@ -310,6 +314,7 @@ function tableInit(ctx){
});
} else {
filterBtn.removeClass("btn-primary");
+ filterBtn.addClass("btn-link");
filterBtn.tooltip('destroy');
}
}
@@ -343,29 +348,65 @@ function tableInit(ctx){
}
}
- function sortColumnClicked(e){
- e.preventDefault();
+ /* Apply an ordering to the current table.
+ *
+ * 1. Find the column heading matching the sortSpecifier
+ * 2. Set its up/down arrow and add .sorted
+ *
+ * orderby: e.g. "-started_on", "completed_on"
+ * colHeading: column heading element to activate (by showing the caret
+ * up/down, depending on sort order); if not set, the correct column
+ * heading is selected from the DOM using orderby as a key
+ */
+ function applyOrderby(orderby, colHeading) {
+ if (!orderby) {
+ return;
+ }
+
+ // We only have one sort at a time so remove existing sort indicators
+ $("#" + ctx.tableName + " th .icon-caret-down").hide();
+ $("#" + ctx.tableName + " th .icon-caret-up").hide();
+ $("#" + ctx.tableName + " th a").removeClass("sorted");
- /* We only have one sort at a time so remove any existing sort indicators */
- $("#"+ctx.tableName+" th .icon-caret-down").hide();
- $("#"+ctx.tableName+" th .icon-caret-up").hide();
- $("#"+ctx.tableName+" th a").removeClass("sorted");
+ // normalise the orderby so we can use it to find the link we want
+ // to style
+ var fieldName = orderby;
+ if (fieldName.indexOf('-') === 0) {
+ fieldName = fieldName.slice(1);
+ }
+
+ // find the table header element which corresponds to the sort field
+ // (if we don't already have it)
+ if (!colHeading) {
+ colHeading = $('[data-sort-field="' + fieldName + '"]');
+ }
+
+ colHeading.addClass("sorted");
+
+ var parent = colHeading.parent();
+
+ if (orderby.indexOf('-') === 0) {
+ parent.children('.icon-caret-up').show();
+ }
+ else {
+ parent.children('.icon-caret-down').show();
+ }
+
+ tableParams.orderby = orderby;
+ loadData(tableParams);
+ }
- var fieldName = $(this).data('field-name');
+ function sortColumnClicked(e){
+ e.preventDefault();
/* if we're already sorted sort the other way */
- if (tableParams.orderby === fieldName &&
+ var orderby = $(this).data('field-name');
+ if (tableParams.orderby === orderby &&
tableParams.orderby.indexOf('-') === -1) {
- tableParams.orderby = '-' + $(this).data('field-name');
- $(this).parent().children('.icon-caret-up').show();
- } else {
- tableParams.orderby = $(this).data('field-name');
- $(this).parent().children('.icon-caret-down').show();
+ orderby = '-' + orderby;
}
- $(this).addClass("sorted");
-
- loadData(tableParams);
+ applyOrderby(orderby, $(this));
}
function pageButtonClicked(e) {
@@ -384,11 +425,13 @@ function tableInit(ctx){
table.find("."+col).show();
} else {
table.find("."+col).hide();
- /* If we're ordered by the column we're hiding remove the order by */
+ // If we're ordered by the column we're hiding remove the order by
+ // and apply the default one instead
if (col === tableParams.orderby ||
'-' + col === tableParams.orderby){
tableParams.orderby = null;
- $("#"+ctx.tableName +" .default-orderby").click();
+
+ applyOrderby(tableParams.default_orderby);
}
}
@@ -415,23 +458,23 @@ function tableInit(ctx){
var hasNoRecords = (Number(filterActionData.count) == 0);
var actionStr = '<div class="radio">' +
- '<input type="radio" name="filter"' +
- ' value="' + filterName + '"';
+ '<label class="filter-title' +
+ (hasNoRecords ? ' text-muted' : '') + '"' +
+ ' for="' + filterName + '">' +
+ '<input type="radio" name="filter"' +
+ ' value="' + filterName + '"';
if (hasNoRecords) {
actionStr += ' disabled="disabled"';
}
actionStr += ' id="' + filterName + '">' +
- '<input type="hidden" name="filter_value" value="on"' +
- ' data-value-for="' + filterName + '">' +
- '<label class="filter-title' +
- (hasNoRecords ? ' muted' : '') + '"' +
- ' for="' + filterName + '">' +
- filterActionData.title +
- ' (' + filterActionData.count + ')' +
- '</label>' +
- '</div>';
+ '<input type="hidden" name="filter_value" value="on"' +
+ ' data-value-for="' + filterName + '">' +
+ filterActionData.title +
+ ' (' + filterActionData.count + ')' +
+ '</label>' +
+ '</div>';
var action = $(actionStr);
@@ -465,22 +508,23 @@ function tableInit(ctx){
*/
function createActionDateRange(filterName, filterValue, filterActionData) {
var action = $('<div class="radio">' +
+ '<label class="filter-title"' +
+ ' for="' + filterName + '">' +
'<input type="radio" name="filter"' +
' value="' + filterName + '" ' +
' id="' + filterName + '">' +
'<input type="hidden" name="filter_value" value=""' +
' data-value-for="' + filterName + '">' +
- '<label class="filter-title"' +
- ' for="' + filterName + '">' +
filterActionData.title +
'</label>' +
- '<input type="text" maxlength="10" class="input-small"' +
+ '<div class="form-inline form-group date-filter-controls">' +
+ '<input type="text" maxlength="10" class="form-control"' +
' data-date-from-for="' + filterName + '">' +
- '<span class="help-inline">to</span>' +
- '<input type="text" maxlength="10" class="input-small"' +
+ '<span>to</span>' +
+ '<input type="text" maxlength="10" class="form-control"' +
' data-date-to-for="' + filterName + '">' +
'<span class="help-inline get-help">(yyyy-mm-dd)</span>' +
- '</div>');
+ '</div></div>');
var radio = action.find('[type="radio"]');
var value = action.find('[data-value-for]');
@@ -621,7 +665,7 @@ function tableInit(ctx){
queryset on the table
*/
var filterActionRadios = $('#filter-actions-' + ctx.tableName);
- var filterApplyBtn = $('[data-role="filter-apply"]');
+ var filterApplyBtn = $('[data-cat="filter-apply"]');
var setApplyButtonState = function (e, filterActionValue) {
if (filterActionValue !== undefined) {
@@ -662,7 +706,7 @@ function tableInit(ctx){
if (action) {
// Setup the current selected filter; default to 'all' if
// no current filter selected
- var radioInput = action.children('input[name="filter"]');
+ var radioInput = action.find('input[name="filter"]');
if ((tableParams.filter &&
tableParams.filter === radioInput.val()) ||
filterActionData.action_name == 'all') {
@@ -788,6 +832,7 @@ function tableInit(ctx){
loadData(tableParams);
- $(this).parent().modal('hide');
+
+ $('#filter-modal-'+ctx.tableName).modal('hide');
});
}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/tests/test.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/tests/test.js
index aac0ba60a..d7953de44 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/tests/test.js
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/tests/test.js
@@ -2,7 +2,6 @@
/* Unit tests for Toaster's JS */
/* libtoaster tests */
-
QUnit.test("Layer alert notification", function(assert) {
var layer = {
"layerdetailurl":"/toastergui/project/1/layer/22",
@@ -43,9 +42,8 @@ QUnit.test("Layer alert notification", function(assert) {
QUnit.test("Project info", function(assert){
var done = assert.async();
- libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl, function(prjInfo){
+ libtoaster.getProjectInfo(libtoaster.ctx.xhrProjectUrl, function(prjInfo){
assert.ok(prjInfo.machine.name);
- assert.ok(prjInfo.releases.length > 0);
assert.ok(prjInfo.layers.length > 0);
assert.ok(prjInfo.freqtargets);
assert.ok(prjInfo.release);
@@ -83,11 +81,11 @@ QUnit.test("Add layer", function(assert){
}, 200);
/* Compare the number of layers before and after the add in the project */
- libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl, function(prjInfo){
+ libtoaster.getProjectInfo(libtoaster.ctx.xhrProjectUrl, function(prjInfo){
var origNumLayers = prjInfo.layers.length;
libtoaster.addRmLayer(layer, true, function(deps){
- libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,
+ libtoaster.getProjectInfo(libtoaster.ctx.xhrProjectUrl,
function(prjInfo){
assert.ok(prjInfo.layers.length > origNumLayers,
"Layer not added to project");
@@ -135,10 +133,10 @@ QUnit.test("Make typeaheads", function(assert){
libtoaster.makeTypeahead(recipesT,
libtoaster.ctx.recipesTypeAheadUrl, {}, function(){});
- assert.ok(recipesT.data('typeahead'));
- assert.ok(layersT.data('typeahead'));
- assert.ok(projectsT.data('typeahead'));
- assert.ok(recipesT.data('typeahead'));
+ assert.ok(recipesT.data('ttTypeahead'));
+ assert.ok(layersT.data('ttTypeahead'));
+ assert.ok(projectsT.data('ttTypeahead'));
+ assert.ok(recipesT.data('ttTypeahead'));
});
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.js b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.js
new file mode 100644
index 000000000..f3efd80cb
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/static/js/typeahead.jquery.js
@@ -0,0 +1,1551 @@
+/*!
+ * typeahead.js 0.11.1
+ * https://github.com/twitter/typeahead.js
+ * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
+ */
+
+(function(root, factory) {
+ if (typeof define === "function" && define.amd) {
+ define("typeahead.js", [ "jquery" ], function(a0) {
+ return factory(a0);
+ });
+ } else if (typeof exports === "object") {
+ module.exports = factory(require("jquery"));
+ } else {
+ factory(jQuery);
+ }
+})(this, function($) {
+ var _ = function() {
+ "use strict";
+ return {
+ isMsie: function() {
+ return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
+ },
+ isBlankString: function(str) {
+ return !str || /^\s*$/.test(str);
+ },
+ escapeRegExChars: function(str) {
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
+ },
+ isString: function(obj) {
+ return typeof obj === "string";
+ },
+ isNumber: function(obj) {
+ return typeof obj === "number";
+ },
+ isArray: $.isArray,
+ isFunction: $.isFunction,
+ isObject: $.isPlainObject,
+ isUndefined: function(obj) {
+ return typeof obj === "undefined";
+ },
+ isElement: function(obj) {
+ return !!(obj && obj.nodeType === 1);
+ },
+ isJQuery: function(obj) {
+ return obj instanceof $;
+ },
+ toStr: function toStr(s) {
+ return _.isUndefined(s) || s === null ? "" : s + "";
+ },
+ bind: $.proxy,
+ each: function(collection, cb) {
+ $.each(collection, reverseArgs);
+ function reverseArgs(index, value) {
+ return cb(value, index);
+ }
+ },
+ map: $.map,
+ filter: $.grep,
+ every: function(obj, test) {
+ var result = true;
+ if (!obj) {
+ return result;
+ }
+ $.each(obj, function(key, val) {
+ if (!(result = test.call(null, val, key, obj))) {
+ return false;
+ }
+ });
+ return !!result;
+ },
+ some: function(obj, test) {
+ var result = false;
+ if (!obj) {
+ return result;
+ }
+ $.each(obj, function(key, val) {
+ if (result = test.call(null, val, key, obj)) {
+ return false;
+ }
+ });
+ return !!result;
+ },
+ mixin: $.extend,
+ identity: function(x) {
+ return x;
+ },
+ clone: function(obj) {
+ return $.extend(true, {}, obj);
+ },
+ getIdGenerator: function() {
+ var counter = 0;
+ return function() {
+ return counter++;
+ };
+ },
+ templatify: function templatify(obj) {
+ return $.isFunction(obj) ? obj : template;
+ function template() {
+ return String(obj);
+ }
+ },
+ defer: function(fn) {
+ setTimeout(fn, 0);
+ },
+ debounce: function(func, wait, immediate) {
+ var timeout, result;
+ return function() {
+ var context = this, args = arguments, later, callNow;
+ later = function() {
+ timeout = null;
+ if (!immediate) {
+ result = func.apply(context, args);
+ }
+ };
+ callNow = immediate && !timeout;
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ if (callNow) {
+ result = func.apply(context, args);
+ }
+ return result;
+ };
+ },
+ throttle: function(func, wait) {
+ var context, args, timeout, result, previous, later;
+ previous = 0;
+ later = function() {
+ previous = new Date();
+ timeout = null;
+ result = func.apply(context, args);
+ };
+ return function() {
+ var now = new Date(), remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0) {
+ clearTimeout(timeout);
+ timeout = null;
+ previous = now;
+ result = func.apply(context, args);
+ } else if (!timeout) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+ },
+ stringify: function(val) {
+ return _.isString(val) ? val : JSON.stringify(val);
+ },
+ noop: function() {}
+ };
+ }();
+ var WWW = function() {
+ "use strict";
+ var defaultClassNames = {
+ wrapper: "twitter-typeahead",
+ input: "tt-input",
+ hint: "tt-hint",
+ menu: "tt-menu",
+ dataset: "tt-dataset",
+ suggestion: "tt-suggestion",
+ selectable: "tt-selectable",
+ empty: "tt-empty",
+ open: "tt-open",
+ cursor: "tt-cursor",
+ highlight: "tt-highlight"
+ };
+ return build;
+ function build(o) {
+ var www, classes;
+ classes = _.mixin({}, defaultClassNames, o);
+ www = {
+ css: buildCss(),
+ classes: classes,
+ html: buildHtml(classes),
+ selectors: buildSelectors(classes)
+ };
+ return {
+ css: www.css,
+ html: www.html,
+ classes: www.classes,
+ selectors: www.selectors,
+ mixin: function(o) {
+ _.mixin(o, www);
+ }
+ };
+ }
+ function buildHtml(c) {
+ return {
+ wrapper: '<span class="' + c.wrapper + '"></span>',
+ menu: '<div class="' + c.menu + '"></div>'
+ };
+ }
+ function buildSelectors(classes) {
+ var selectors = {};
+ _.each(classes, function(v, k) {
+ selectors[k] = "." + v;
+ });
+ return selectors;
+ }
+ function buildCss() {
+ var css = {
+ wrapper: {
+ position: "relative",
+ display: "inline-block"
+ },
+ hint: {
+ position: "absolute",
+ top: "0",
+ left: "0",
+ borderColor: "transparent",
+ boxShadow: "none",
+ opacity: "1"
+ },
+ input: {
+ position: "relative",
+ verticalAlign: "top",
+ backgroundColor: "transparent"
+ },
+ inputWithNoHint: {
+ position: "relative",
+ verticalAlign: "top"
+ },
+ menu: {
+ position: "absolute",
+ top: "100%",
+ left: "0",
+ zIndex: "100",
+ display: "none"
+ },
+ ltr: {
+ left: "0",
+ right: "auto"
+ },
+ rtl: {
+ left: "auto",
+ right: " 0"
+ }
+ };
+ if (_.isMsie()) {
+ _.mixin(css.input, {
+ backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
+ });
+ }
+ return css;
+ }
+ }();
+ var EventBus = function() {
+ "use strict";
+ var namespace, deprecationMap;
+ namespace = "typeahead:";
+ deprecationMap = {
+ render: "rendered",
+ cursorchange: "cursorchanged",
+ select: "selected",
+ autocomplete: "autocompleted"
+ };
+ function EventBus(o) {
+ if (!o || !o.el) {
+ $.error("EventBus initialized without el");
+ }
+ this.$el = $(o.el);
+ }
+ _.mixin(EventBus.prototype, {
+ _trigger: function(type, args) {
+ var $e;
+ $e = $.Event(namespace + type);
+ (args = args || []).unshift($e);
+ this.$el.trigger.apply(this.$el, args);
+ return $e;
+ },
+ before: function(type) {
+ var args, $e;
+ args = [].slice.call(arguments, 1);
+ $e = this._trigger("before" + type, args);
+ return $e.isDefaultPrevented();
+ },
+ trigger: function(type) {
+ var deprecatedType;
+ this._trigger(type, [].slice.call(arguments, 1));
+ if (deprecatedType = deprecationMap[type]) {
+ this._trigger(deprecatedType, [].slice.call(arguments, 1));
+ }
+ }
+ });
+ return EventBus;
+ }();
+ var EventEmitter = function() {
+ "use strict";
+ var splitter = /\s+/, nextTick = getNextTick();
+ return {
+ onSync: onSync,
+ onAsync: onAsync,
+ off: off,
+ trigger: trigger
+ };
+ function on(method, types, cb, context) {
+ var type;
+ if (!cb) {
+ return this;
+ }
+ types = types.split(splitter);
+ cb = context ? bindContext(cb, context) : cb;
+ this._callbacks = this._callbacks || {};
+ while (type = types.shift()) {
+ this._callbacks[type] = this._callbacks[type] || {
+ sync: [],
+ async: []
+ };
+ this._callbacks[type][method].push(cb);
+ }
+ return this;
+ }
+ function onAsync(types, cb, context) {
+ return on.call(this, "async", types, cb, context);
+ }
+ function onSync(types, cb, context) {
+ return on.call(this, "sync", types, cb, context);
+ }
+ function off(types) {
+ var type;
+ if (!this._callbacks) {
+ return this;
+ }
+ types = types.split(splitter);
+ while (type = types.shift()) {
+ delete this._callbacks[type];
+ }
+ return this;
+ }
+ function trigger(types) {
+ var type, callbacks, args, syncFlush, asyncFlush;
+ if (!this._callbacks) {
+ return this;
+ }
+ types = types.split(splitter);
+ args = [].slice.call(arguments, 1);
+ while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
+ syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
+ asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
+ syncFlush() && nextTick(asyncFlush);
+ }
+ return this;
+ }
+ function getFlush(callbacks, context, args) {
+ return flush;
+ function flush() {
+ var cancelled;
+ for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
+ cancelled = callbacks[i].apply(context, args) === false;
+ }
+ return !cancelled;
+ }
+ }
+ function getNextTick() {
+ var nextTickFn;
+ if (window.setImmediate) {
+ nextTickFn = function nextTickSetImmediate(fn) {
+ setImmediate(function() {
+ fn();
+ });
+ };
+ } else {
+ nextTickFn = function nextTickSetTimeout(fn) {
+ setTimeout(function() {
+ fn();
+ }, 0);
+ };
+ }
+ return nextTickFn;
+ }
+ function bindContext(fn, context) {
+ return fn.bind ? fn.bind(context) : function() {
+ fn.apply(context, [].slice.call(arguments, 0));
+ };
+ }
+ }();
+ var highlight = function(doc) {
+ "use strict";
+ var defaults = {
+ node: null,
+ pattern: null,
+ tagName: "strong",
+ className: null,
+ wordsOnly: false,
+ caseSensitive: false
+ };
+ return function hightlight(o) {
+ var regex;
+ o = _.mixin({}, defaults, o);
+ if (!o.node || !o.pattern) {
+ return;
+ }
+ o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
+ regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
+ traverse(o.node, hightlightTextNode);
+ function hightlightTextNode(textNode) {
+ var match, patternNode, wrapperNode;
+ if (match = regex.exec(textNode.data)) {
+ wrapperNode = doc.createElement(o.tagName);
+ o.className && (wrapperNode.className = o.className);
+ patternNode = textNode.splitText(match.index);
+ patternNode.splitText(match[0].length);
+ wrapperNode.appendChild(patternNode.cloneNode(true));
+ textNode.parentNode.replaceChild(wrapperNode, patternNode);
+ }
+ return !!match;
+ }
+ function traverse(el, hightlightTextNode) {
+ var childNode, TEXT_NODE_TYPE = 3;
+ for (var i = 0; i < el.childNodes.length; i++) {
+ childNode = el.childNodes[i];
+ if (childNode.nodeType === TEXT_NODE_TYPE) {
+ i += hightlightTextNode(childNode) ? 1 : 0;
+ } else {
+ traverse(childNode, hightlightTextNode);
+ }
+ }
+ }
+ };
+ function getRegex(patterns, caseSensitive, wordsOnly) {
+ var escapedPatterns = [], regexStr;
+ for (var i = 0, len = patterns.length; i < len; i++) {
+ escapedPatterns.push(_.escapeRegExChars(patterns[i]));
+ }
+ regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
+ return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
+ }
+ }(window.document);
+ var Input = function() {
+ "use strict";
+ var specialKeyCodeMap;
+ specialKeyCodeMap = {
+ 9: "tab",
+ 27: "esc",
+ 37: "left",
+ 39: "right",
+ 13: "enter",
+ 38: "up",
+ 40: "down"
+ };
+ function Input(o, www) {
+ o = o || {};
+ if (!o.input) {
+ $.error("input is missing");
+ }
+ www.mixin(this);
+ this.$hint = $(o.hint);
+ this.$input = $(o.input);
+ this.query = this.$input.val();
+ this.queryWhenFocused = this.hasFocus() ? this.query : null;
+ this.$overflowHelper = buildOverflowHelper(this.$input);
+ this._checkLanguageDirection();
+ if (this.$hint.length === 0) {
+ this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
+ }
+ }
+ Input.normalizeQuery = function(str) {
+ return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
+ };
+ _.mixin(Input.prototype, EventEmitter, {
+ _onBlur: function onBlur() {
+ this.resetInputValue();
+ this.trigger("blurred");
+ },
+ _onFocus: function onFocus() {
+ this.queryWhenFocused = this.query;
+ this.trigger("focused");
+ },
+ _onKeydown: function onKeydown($e) {
+ var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
+ this._managePreventDefault(keyName, $e);
+ if (keyName && this._shouldTrigger(keyName, $e)) {
+ this.trigger(keyName + "Keyed", $e);
+ }
+ },
+ _onInput: function onInput() {
+ this._setQuery(this.getInputValue());
+ this.clearHintIfInvalid();
+ this._checkLanguageDirection();
+ },
+ _managePreventDefault: function managePreventDefault(keyName, $e) {
+ var preventDefault;
+ switch (keyName) {
+ case "up":
+ case "down":
+ preventDefault = !withModifier($e);
+ break;
+
+ default:
+ preventDefault = false;
+ }
+ preventDefault && $e.preventDefault();
+ },
+ _shouldTrigger: function shouldTrigger(keyName, $e) {
+ var trigger;
+ switch (keyName) {
+ case "tab":
+ trigger = !withModifier($e);
+ break;
+
+ default:
+ trigger = true;
+ }
+ return trigger;
+ },
+ _checkLanguageDirection: function checkLanguageDirection() {
+ var dir = (this.$input.css("direction") || "ltr").toLowerCase();
+ if (this.dir !== dir) {
+ this.dir = dir;
+ this.$hint.attr("dir", dir);
+ this.trigger("langDirChanged", dir);
+ }
+ },
+ _setQuery: function setQuery(val, silent) {
+ var areEquivalent, hasDifferentWhitespace;
+ areEquivalent = areQueriesEquivalent(val, this.query);
+ hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;
+ this.query = val;
+ if (!silent && !areEquivalent) {
+ this.trigger("queryChanged", this.query);
+ } else if (!silent && hasDifferentWhitespace) {
+ this.trigger("whitespaceChanged", this.query);
+ }
+ },
+ bind: function() {
+ var that = this, onBlur, onFocus, onKeydown, onInput;
+ onBlur = _.bind(this._onBlur, this);
+ onFocus = _.bind(this._onFocus, this);
+ onKeydown = _.bind(this._onKeydown, this);
+ onInput = _.bind(this._onInput, this);
+ this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
+ if (!_.isMsie() || _.isMsie() > 9) {
+ this.$input.on("input.tt", onInput);
+ } else {
+ this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
+ if (specialKeyCodeMap[$e.which || $e.keyCode]) {
+ return;
+ }
+ _.defer(_.bind(that._onInput, that, $e));
+ });
+ }
+ return this;
+ },
+ focus: function focus() {
+ this.$input.focus();
+ },
+ blur: function blur() {
+ this.$input.blur();
+ },
+ getLangDir: function getLangDir() {
+ return this.dir;
+ },
+ getQuery: function getQuery() {
+ return this.query || "";
+ },
+ setQuery: function setQuery(val, silent) {
+ this.setInputValue(val);
+ this._setQuery(val, silent);
+ },
+ hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {
+ return this.query !== this.queryWhenFocused;
+ },
+ getInputValue: function getInputValue() {
+ return this.$input.val();
+ },
+ setInputValue: function setInputValue(value) {
+ this.$input.val(value);
+ this.clearHintIfInvalid();
+ this._checkLanguageDirection();
+ },
+ resetInputValue: function resetInputValue() {
+ this.setInputValue(this.query);
+ },
+ getHint: function getHint() {
+ return this.$hint.val();
+ },
+ setHint: function setHint(value) {
+ this.$hint.val(value);
+ },
+ clearHint: function clearHint() {
+ this.setHint("");
+ },
+ clearHintIfInvalid: function clearHintIfInvalid() {
+ var val, hint, valIsPrefixOfHint, isValid;
+ val = this.getInputValue();
+ hint = this.getHint();
+ valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
+ isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
+ !isValid && this.clearHint();
+ },
+ hasFocus: function hasFocus() {
+ return this.$input.is(":focus");
+ },
+ hasOverflow: function hasOverflow() {
+ var constraint = this.$input.width() - 2;
+ this.$overflowHelper.text(this.getInputValue());
+ return this.$overflowHelper.width() >= constraint;
+ },
+ isCursorAtEnd: function() {
+ var valueLength, selectionStart, range;
+ valueLength = this.$input.val().length;
+ selectionStart = this.$input[0].selectionStart;
+ if (_.isNumber(selectionStart)) {
+ return selectionStart === valueLength;
+ } else if (document.selection) {
+ range = document.selection.createRange();
+ range.moveStart("character", -valueLength);
+ return valueLength === range.text.length;
+ }
+ return true;
+ },
+ destroy: function destroy() {
+ this.$hint.off(".tt");
+ this.$input.off(".tt");
+ this.$overflowHelper.remove();
+ this.$hint = this.$input = this.$overflowHelper = $("<div>");
+ }
+ });
+ return Input;
+ function buildOverflowHelper($input) {
+ return $('<pre aria-hidden="true"></pre>').css({
+ position: "absolute",
+ visibility: "hidden",
+ whiteSpace: "pre",
+ fontFamily: $input.css("font-family"),
+ fontSize: $input.css("font-size"),
+ fontStyle: $input.css("font-style"),
+ fontVariant: $input.css("font-variant"),
+ fontWeight: $input.css("font-weight"),
+ wordSpacing: $input.css("word-spacing"),
+ letterSpacing: $input.css("letter-spacing"),
+ textIndent: $input.css("text-indent"),
+ textRendering: $input.css("text-rendering"),
+ textTransform: $input.css("text-transform")
+ }).insertAfter($input);
+ }
+ function areQueriesEquivalent(a, b) {
+ return Input.normalizeQuery(a) === Input.normalizeQuery(b);
+ }
+ function withModifier($e) {
+ return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
+ }
+ }();
+ var Dataset = function() {
+ "use strict";
+ var keys, nameGenerator;
+ keys = {
+ val: "tt-selectable-display",
+ obj: "tt-selectable-object"
+ };
+ nameGenerator = _.getIdGenerator();
+ function Dataset(o, www) {
+ o = o || {};
+ o.templates = o.templates || {};
+ o.templates.notFound = o.templates.notFound || o.templates.empty;
+ if (!o.source) {
+ $.error("missing source");
+ }
+ if (!o.node) {
+ $.error("missing node");
+ }
+ if (o.name && !isValidName(o.name)) {
+ $.error("invalid dataset name: " + o.name);
+ }
+ www.mixin(this);
+ this.highlight = !!o.highlight;
+ this.name = o.name || nameGenerator();
+ this.limit = o.limit || 5;
+ this.displayFn = getDisplayFn(o.display || o.displayKey);
+ this.templates = getTemplates(o.templates, this.displayFn);
+ this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
+ this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
+ this._resetLastSuggestion();
+ this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
+ }
+ Dataset.extractData = function extractData(el) {
+ var $el = $(el);
+ if ($el.data(keys.obj)) {
+ return {
+ val: $el.data(keys.val) || "",
+ obj: $el.data(keys.obj) || null
+ };
+ }
+ return null;
+ };
+ _.mixin(Dataset.prototype, EventEmitter, {
+ _overwrite: function overwrite(query, suggestions) {
+ suggestions = suggestions || [];
+ if (suggestions.length) {
+ this._renderSuggestions(query, suggestions);
+ } else if (this.async && this.templates.pending) {
+ this._renderPending(query);
+ } else if (!this.async && this.templates.notFound) {
+ this._renderNotFound(query);
+ } else {
+ this._empty();
+ }
+ this.trigger("rendered", this.name, suggestions, false);
+ },
+ _append: function append(query, suggestions) {
+ suggestions = suggestions || [];
+ if (suggestions.length && this.$lastSuggestion.length) {
+ this._appendSuggestions(query, suggestions);
+ } else if (suggestions.length) {
+ this._renderSuggestions(query, suggestions);
+ } else if (!this.$lastSuggestion.length && this.templates.notFound) {
+ this._renderNotFound(query);
+ }
+ this.trigger("rendered", this.name, suggestions, true);
+ },
+ _renderSuggestions: function renderSuggestions(query, suggestions) {
+ var $fragment;
+ $fragment = this._getSuggestionsFragment(query, suggestions);
+ this.$lastSuggestion = $fragment.children().last();
+ this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));
+ },
+ _appendSuggestions: function appendSuggestions(query, suggestions) {
+ var $fragment, $lastSuggestion;
+ $fragment = this._getSuggestionsFragment(query, suggestions);
+ $lastSuggestion = $fragment.children().last();
+ this.$lastSuggestion.after($fragment);
+ this.$lastSuggestion = $lastSuggestion;
+ },
+ _renderPending: function renderPending(query) {
+ var template = this.templates.pending;
+ this._resetLastSuggestion();
+ template && this.$el.html(template({
+ query: query,
+ dataset: this.name
+ }));
+ },
+ _renderNotFound: function renderNotFound(query) {
+ var template = this.templates.notFound;
+ this._resetLastSuggestion();
+ template && this.$el.html(template({
+ query: query,
+ dataset: this.name
+ }));
+ },
+ _empty: function empty() {
+ this.$el.empty();
+ this._resetLastSuggestion();
+ },
+ _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {
+ var that = this, fragment;
+ fragment = document.createDocumentFragment();
+ _.each(suggestions, function getSuggestionNode(suggestion) {
+ var $el, context;
+ context = that._injectQuery(query, suggestion);
+ $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
+ fragment.appendChild($el[0]);
+ });
+ this.highlight && highlight({
+ className: this.classes.highlight,
+ node: fragment,
+ pattern: query
+ });
+ return $(fragment);
+ },
+ _getFooter: function getFooter(query, suggestions) {
+ return this.templates.footer ? this.templates.footer({
+ query: query,
+ suggestions: suggestions,
+ dataset: this.name
+ }) : null;
+ },
+ _getHeader: function getHeader(query, suggestions) {
+ return this.templates.header ? this.templates.header({
+ query: query,
+ suggestions: suggestions,
+ dataset: this.name
+ }) : null;
+ },
+ _resetLastSuggestion: function resetLastSuggestion() {
+ this.$lastSuggestion = $();
+ },
+ _injectQuery: function injectQuery(query, obj) {
+ return _.isObject(obj) ? _.mixin({
+ _query: query
+ }, obj) : obj;
+ },
+ update: function update(query) {
+ var that = this, canceled = false, syncCalled = false, rendered = 0;
+ this.cancel();
+ this.cancel = function cancel() {
+ canceled = true;
+ that.cancel = $.noop;
+ that.async && that.trigger("asyncCanceled", query);
+ };
+ this.source(query, sync, async);
+ !syncCalled && sync([]);
+ function sync(suggestions) {
+ if (syncCalled) {
+ return;
+ }
+ syncCalled = true;
+ suggestions = (suggestions || []).slice(0, that.limit);
+ rendered = suggestions.length;
+ that._overwrite(query, suggestions);
+ if (rendered < that.limit && that.async) {
+ that.trigger("asyncRequested", query);
+ }
+ }
+ function async(suggestions) {
+ suggestions = suggestions || [];
+ if (!canceled && rendered < that.limit) {
+ that.cancel = $.noop;
+ rendered += suggestions.length;
+
+ // HACK: because we don't have a synchronous way of
+ // retrieving results, we use the async function every
+ // time we update the drop-down; however, the typeahead
+ // does some internal book-keeping which means that we
+ // only get the additional items in the drop-down when
+ // the next set of results is fetched, instead of all
+ // of them (it appears to implicitly track which
+ // results have already been shown in the drop-down); by
+ // forcing an overwrite, we see all of the new results
+ // every time we fetch a set of suggestions
+ //that._append(query, suggestions.slice(0, that.limit - rendered));
+ that._overwrite(query, suggestions);
+
+ that.async && that.trigger("asyncReceived", query);
+ }
+ }
+ },
+ cancel: $.noop,
+ clear: function clear() {
+ this._empty();
+ this.cancel();
+ this.trigger("cleared");
+ },
+ isEmpty: function isEmpty() {
+ return this.$el.is(":empty");
+ },
+ destroy: function destroy() {
+ this.$el = $("<div>");
+ }
+ });
+ return Dataset;
+ function getDisplayFn(display) {
+ display = display || _.stringify;
+ return _.isFunction(display) ? display : displayFn;
+ function displayFn(obj) {
+ return obj[display];
+ }
+ }
+ function getTemplates(templates, displayFn) {
+ return {
+ notFound: templates.notFound && _.templatify(templates.notFound),
+ pending: templates.pending && _.templatify(templates.pending),
+ header: templates.header && _.templatify(templates.header),
+ footer: templates.footer && _.templatify(templates.footer),
+ suggestion: templates.suggestion || suggestionTemplate
+ };
+ function suggestionTemplate(context) {
+ return $("<div>").text(displayFn(context));
+ }
+ }
+ function isValidName(str) {
+ return /^[_a-zA-Z0-9-]+$/.test(str);
+ }
+ }();
+ var Menu = function() {
+ "use strict";
+ function Menu(o, www) {
+ var that = this;
+ o = o || {};
+ if (!o.node) {
+ $.error("node is required");
+ }
+ www.mixin(this);
+ this.$node = $(o.node);
+ this.query = null;
+ this.datasets = _.map(o.datasets, initializeDataset);
+ function initializeDataset(oDataset) {
+ var node = that.$node.find(oDataset.node).first();
+ oDataset.node = node.length ? node : $("<div>").appendTo(that.$node);
+ return new Dataset(oDataset, www);
+ }
+ }
+ _.mixin(Menu.prototype, EventEmitter, {
+ _onSelectableClick: function onSelectableClick($e) {
+ this.trigger("selectableClicked", $($e.currentTarget));
+ },
+ _onRendered: function onRendered(type, dataset, suggestions, async) {
+ this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
+ this.trigger("datasetRendered", dataset, suggestions, async);
+ },
+ _onCleared: function onCleared() {
+ this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
+ this.trigger("datasetCleared");
+ },
+ _propagate: function propagate() {
+ this.trigger.apply(this, arguments);
+ },
+ _allDatasetsEmpty: function allDatasetsEmpty() {
+ return _.every(this.datasets, isDatasetEmpty);
+ function isDatasetEmpty(dataset) {
+ return dataset.isEmpty();
+ }
+ },
+ _getSelectables: function getSelectables() {
+ return this.$node.find(this.selectors.selectable);
+ },
+ _removeCursor: function _removeCursor() {
+ var $selectable = this.getActiveSelectable();
+ $selectable && $selectable.removeClass(this.classes.cursor);
+ },
+ _ensureVisible: function ensureVisible($el) {
+ var elTop, elBottom, nodeScrollTop, nodeHeight;
+ elTop = $el.position().top;
+ elBottom = elTop + $el.outerHeight(true);
+ nodeScrollTop = this.$node.scrollTop();
+ nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10);
+ if (elTop < 0) {
+ this.$node.scrollTop(nodeScrollTop + elTop);
+ } else if (nodeHeight < elBottom) {
+ this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
+ }
+ },
+ bind: function() {
+ var that = this, onSelectableClick;
+ onSelectableClick = _.bind(this._onSelectableClick, this);
+ this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
+ _.each(this.datasets, function(dataset) {
+ dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
+ });
+ return this;
+ },
+ isOpen: function isOpen() {
+ return this.$node.hasClass(this.classes.open);
+ },
+ open: function open() {
+ this.$node.addClass(this.classes.open);
+ },
+ close: function close() {
+ this.$node.removeClass(this.classes.open);
+ this._removeCursor();
+ },
+ setLanguageDirection: function setLanguageDirection(dir) {
+ this.$node.attr("dir", dir);
+ },
+ selectableRelativeToCursor: function selectableRelativeToCursor(delta) {
+ var $selectables, $oldCursor, oldIndex, newIndex;
+ $oldCursor = this.getActiveSelectable();
+ $selectables = this._getSelectables();
+ oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;
+ newIndex = oldIndex + delta;
+ newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;
+ newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;
+ return newIndex === -1 ? null : $selectables.eq(newIndex);
+ },
+ setCursor: function setCursor($selectable) {
+ this._removeCursor();
+ if ($selectable = $selectable && $selectable.first()) {
+ $selectable.addClass(this.classes.cursor);
+ this._ensureVisible($selectable);
+ }
+ },
+ getSelectableData: function getSelectableData($el) {
+ return $el && $el.length ? Dataset.extractData($el) : null;
+ },
+ getActiveSelectable: function getActiveSelectable() {
+ var $selectable = this._getSelectables().filter(this.selectors.cursor).first();
+ return $selectable.length ? $selectable : null;
+ },
+ getTopSelectable: function getTopSelectable() {
+ var $selectable = this._getSelectables().first();
+ return $selectable.length ? $selectable : null;
+ },
+ update: function update(query) {
+ var isValidUpdate = query !== this.query;
+ if (isValidUpdate) {
+ this.query = query;
+ _.each(this.datasets, updateDataset);
+ }
+ return isValidUpdate;
+ function updateDataset(dataset) {
+ dataset.update(query);
+ }
+ },
+ empty: function empty() {
+ _.each(this.datasets, clearDataset);
+ this.query = null;
+ this.$node.addClass(this.classes.empty);
+ function clearDataset(dataset) {
+ dataset.clear();
+ }
+ },
+ destroy: function destroy() {
+ this.$node.off(".tt");
+ this.$node = $("<div>");
+ _.each(this.datasets, destroyDataset);
+ function destroyDataset(dataset) {
+ dataset.destroy();
+ }
+ }
+ });
+ return Menu;
+ }();
+ var DefaultMenu = function() {
+ "use strict";
+ var s = Menu.prototype;
+ function DefaultMenu() {
+ Menu.apply(this, [].slice.call(arguments, 0));
+ }
+ _.mixin(DefaultMenu.prototype, Menu.prototype, {
+ open: function open() {
+ !this._allDatasetsEmpty() && this._show();
+ return s.open.apply(this, [].slice.call(arguments, 0));
+ },
+ close: function close() {
+ this._hide();
+ return s.close.apply(this, [].slice.call(arguments, 0));
+ },
+ _onRendered: function onRendered() {
+ if (this._allDatasetsEmpty()) {
+ this._hide();
+ } else {
+ this.isOpen() && this._show();
+ }
+ return s._onRendered.apply(this, [].slice.call(arguments, 0));
+ },
+ _onCleared: function onCleared() {
+ if (this._allDatasetsEmpty()) {
+ this._hide();
+ } else {
+ this.isOpen() && this._show();
+ }
+ return s._onCleared.apply(this, [].slice.call(arguments, 0));
+ },
+ setLanguageDirection: function setLanguageDirection(dir) {
+ this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl);
+ return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));
+ },
+ _hide: function hide() {
+ this.$node.hide();
+ },
+ _show: function show() {
+ this.$node.css("display", "block");
+ }
+ });
+ return DefaultMenu;
+ }();
+ var Typeahead = function() {
+ "use strict";
+ function Typeahead(o, www) {
+ var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;
+ o = o || {};
+ if (!o.input) {
+ $.error("missing input");
+ }
+ if (!o.menu) {
+ $.error("missing menu");
+ }
+ if (!o.eventBus) {
+ $.error("missing event bus");
+ }
+ www.mixin(this);
+ this.eventBus = o.eventBus;
+ this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
+ this.input = o.input;
+ this.menu = o.menu;
+ this.enabled = true;
+ this.active = false;
+ this.input.hasFocus() && this.activate();
+ this.dir = this.input.getLangDir();
+ this._hacks();
+ this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this);
+ onFocused = c(this, "activate", "open", "_onFocused");
+ onBlurred = c(this, "deactivate", "_onBlurred");
+ onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed");
+ onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed");
+ onEscKeyed = c(this, "isActive", "_onEscKeyed");
+ onUpKeyed = c(this, "isActive", "open", "_onUpKeyed");
+ onDownKeyed = c(this, "isActive", "open", "_onDownKeyed");
+ onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed");
+ onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed");
+ onQueryChanged = c(this, "_openIfActive", "_onQueryChanged");
+ onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged");
+ this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this);
+ }
+ _.mixin(Typeahead.prototype, {
+ _hacks: function hacks() {
+ var $input, $menu;
+ $input = this.input.$input || $("<div>");
+ $menu = this.menu.$node || $("<div>");
+ $input.on("blur.tt", function($e) {
+ var active, isActive, hasActive;
+ active = document.activeElement;
+ isActive = $menu.is(active);
+ hasActive = $menu.has(active).length > 0;
+ if (_.isMsie() && (isActive || hasActive)) {
+ $e.preventDefault();
+ $e.stopImmediatePropagation();
+ _.defer(function() {
+ $input.focus();
+ });
+ }
+ });
+ $menu.on("mousedown.tt", function($e) {
+ $e.preventDefault();
+ });
+ },
+ _onSelectableClicked: function onSelectableClicked(type, $el) {
+ this.select($el);
+ },
+ _onDatasetCleared: function onDatasetCleared() {
+ this._updateHint();
+ },
+ _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {
+ this._updateHint();
+ this.eventBus.trigger("render", suggestions, async, dataset);
+ },
+ _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
+ this.eventBus.trigger("asyncrequest", query, dataset);
+ },
+ _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {
+ this.eventBus.trigger("asynccancel", query, dataset);
+ },
+ _onAsyncReceived: function onAsyncReceived(type, dataset, query) {
+ this.eventBus.trigger("asyncreceive", query, dataset);
+ },
+ _onFocused: function onFocused() {
+ this._minLengthMet() && this.menu.update(this.input.getQuery());
+ },
+ _onBlurred: function onBlurred() {
+ if (this.input.hasQueryChangedSinceLastFocus()) {
+ this.eventBus.trigger("change", this.input.getQuery());
+ }
+ },
+ _onEnterKeyed: function onEnterKeyed(type, $e) {
+ var $selectable;
+ if ($selectable = this.menu.getActiveSelectable()) {
+ this.select($selectable) && $e.preventDefault();
+ }
+ },
+ _onTabKeyed: function onTabKeyed(type, $e) {
+ var $selectable;
+ if ($selectable = this.menu.getActiveSelectable()) {
+ this.select($selectable) && $e.preventDefault();
+ } else if ($selectable = this.menu.getTopSelectable()) {
+ this.autocomplete($selectable) && $e.preventDefault();
+ }
+ },
+ _onEscKeyed: function onEscKeyed() {
+ this.close();
+ },
+ _onUpKeyed: function onUpKeyed() {
+ this.moveCursor(-1);
+ },
+ _onDownKeyed: function onDownKeyed() {
+ this.moveCursor(+1);
+ },
+ _onLeftKeyed: function onLeftKeyed() {
+ if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
+ this.autocomplete(this.menu.getTopSelectable());
+ }
+ },
+ _onRightKeyed: function onRightKeyed() {
+ if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
+ this.autocomplete(this.menu.getTopSelectable());
+ }
+ },
+ _onQueryChanged: function onQueryChanged(e, query) {
+ this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();
+ },
+ _onWhitespaceChanged: function onWhitespaceChanged() {
+ this._updateHint();
+ },
+ _onLangDirChanged: function onLangDirChanged(e, dir) {
+ if (this.dir !== dir) {
+ this.dir = dir;
+ this.menu.setLanguageDirection(dir);
+ }
+ },
+ _openIfActive: function openIfActive() {
+ this.isActive() && this.open();
+ },
+ _minLengthMet: function minLengthMet(query) {
+ query = _.isString(query) ? query : this.input.getQuery() || "";
+ return query.length >= this.minLength;
+ },
+ _updateHint: function updateHint() {
+ var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;
+ $selectable = this.menu.getTopSelectable();
+ data = this.menu.getSelectableData($selectable);
+ val = this.input.getInputValue();
+ if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {
+ query = Input.normalizeQuery(val);
+ escapedQuery = _.escapeRegExChars(query);
+ frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
+ match = frontMatchRegEx.exec(data.val);
+ match && this.input.setHint(val + match[1]);
+ } else {
+ this.input.clearHint();
+ }
+ },
+ isEnabled: function isEnabled() {
+ return this.enabled;
+ },
+ enable: function enable() {
+ this.enabled = true;
+ },
+ disable: function disable() {
+ this.enabled = false;
+ },
+ isActive: function isActive() {
+ return this.active;
+ },
+ activate: function activate() {
+ if (this.isActive()) {
+ return true;
+ } else if (!this.isEnabled() || this.eventBus.before("active")) {
+ return false;
+ } else {
+ this.active = true;
+ this.eventBus.trigger("active");
+ return true;
+ }
+ },
+ deactivate: function deactivate() {
+ if (!this.isActive()) {
+ return true;
+ } else if (this.eventBus.before("idle")) {
+ return false;
+ } else {
+ this.active = false;
+ this.close();
+ this.eventBus.trigger("idle");
+ return true;
+ }
+ },
+ isOpen: function isOpen() {
+ return this.menu.isOpen();
+ },
+ open: function open() {
+ if (!this.isOpen() && !this.eventBus.before("open")) {
+ this.menu.open();
+ this._updateHint();
+ this.eventBus.trigger("open");
+ }
+ return this.isOpen();
+ },
+ close: function close() {
+ if (this.isOpen() && !this.eventBus.before("close")) {
+ this.menu.close();
+ this.input.clearHint();
+ this.input.resetInputValue();
+ this.eventBus.trigger("close");
+ }
+ return !this.isOpen();
+ },
+ setVal: function setVal(val) {
+ this.input.setQuery(_.toStr(val));
+ },
+ getVal: function getVal() {
+ return this.input.getQuery();
+ },
+ select: function select($selectable) {
+ var data = this.menu.getSelectableData($selectable);
+ if (data && !this.eventBus.before("select", data.obj)) {
+ this.input.setQuery(data.val, true);
+ this.eventBus.trigger("select", data.obj);
+ this.close();
+ return true;
+ }
+ return false;
+ },
+ autocomplete: function autocomplete($selectable) {
+ var query, data, isValid;
+ query = this.input.getQuery();
+ data = this.menu.getSelectableData($selectable);
+ isValid = data && query !== data.val;
+ if (isValid && !this.eventBus.before("autocomplete", data.obj)) {
+ this.input.setQuery(data.val);
+ this.eventBus.trigger("autocomplete", data.obj);
+ return true;
+ }
+ return false;
+ },
+ moveCursor: function moveCursor(delta) {
+ var query, $candidate, data, payload, cancelMove;
+ query = this.input.getQuery();
+ $candidate = this.menu.selectableRelativeToCursor(delta);
+ data = this.menu.getSelectableData($candidate);
+ payload = data ? data.obj : null;
+ cancelMove = this._minLengthMet() && this.menu.update(query);
+ if (!cancelMove && !this.eventBus.before("cursorchange", payload)) {
+ this.menu.setCursor($candidate);
+ if (data) {
+ this.input.setInputValue(data.val);
+ } else {
+ this.input.resetInputValue();
+ this._updateHint();
+ }
+ this.eventBus.trigger("cursorchange", payload);
+ return true;
+ }
+ return false;
+ },
+ destroy: function destroy() {
+ this.input.destroy();
+ this.menu.destroy();
+ }
+ });
+ return Typeahead;
+ function c(ctx) {
+ var methods = [].slice.call(arguments, 1);
+ return function() {
+ var args = [].slice.call(arguments);
+ _.each(methods, function(method) {
+ return ctx[method].apply(ctx, args);
+ });
+ };
+ }
+ }();
+ (function() {
+ "use strict";
+ var old, keys, methods;
+ old = $.fn.typeahead;
+ keys = {
+ www: "tt-www",
+ attrs: "tt-attrs",
+ typeahead: "tt-typeahead"
+ };
+ methods = {
+ initialize: function initialize(o, datasets) {
+ var www;
+ datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
+ o = o || {};
+ www = WWW(o.classNames);
+ return this.each(attach);
+ function attach() {
+ var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;
+ _.each(datasets, function(d) {
+ d.highlight = !!o.highlight;
+ });
+ $input = $(this);
+ $wrapper = $(www.html.wrapper);
+ $hint = $elOrNull(o.hint);
+ $menu = $elOrNull(o.menu);
+ defaultHint = o.hint !== false && !$hint;
+ defaultMenu = o.menu !== false && !$menu;
+ defaultHint && ($hint = buildHintFromInput($input, www));
+ defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
+ $hint && $hint.val("");
+ $input = prepInput($input, www);
+ if (defaultHint || defaultMenu) {
+ $wrapper.css(www.css.wrapper);
+ $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
+ $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);
+ }
+ MenuConstructor = defaultMenu ? DefaultMenu : Menu;
+ eventBus = new EventBus({
+ el: $input
+ });
+ input = new Input({
+ hint: $hint,
+ input: $input
+ }, www);
+ menu = new MenuConstructor({
+ node: $menu,
+ datasets: datasets
+ }, www);
+ typeahead = new Typeahead({
+ input: input,
+ menu: menu,
+ eventBus: eventBus,
+ minLength: o.minLength
+ }, www);
+ $input.data(keys.www, www);
+ $input.data(keys.typeahead, typeahead);
+ }
+ },
+ isEnabled: function isEnabled() {
+ var enabled;
+ ttEach(this.first(), function(t) {
+ enabled = t.isEnabled();
+ });
+ return enabled;
+ },
+ enable: function enable() {
+ ttEach(this, function(t) {
+ t.enable();
+ });
+ return this;
+ },
+ disable: function disable() {
+ ttEach(this, function(t) {
+ t.disable();
+ });
+ return this;
+ },
+ isActive: function isActive() {
+ var active;
+ ttEach(this.first(), function(t) {
+ active = t.isActive();
+ });
+ return active;
+ },
+ activate: function activate() {
+ ttEach(this, function(t) {
+ t.activate();
+ });
+ return this;
+ },
+ deactivate: function deactivate() {
+ ttEach(this, function(t) {
+ t.deactivate();
+ });
+ return this;
+ },
+ isOpen: function isOpen() {
+ var open;
+ ttEach(this.first(), function(t) {
+ open = t.isOpen();
+ });
+ return open;
+ },
+ open: function open() {
+ ttEach(this, function(t) {
+ t.open();
+ });
+ return this;
+ },
+ close: function close() {
+ ttEach(this, function(t) {
+ t.close();
+ });
+ return this;
+ },
+ select: function select(el) {
+ var success = false, $el = $(el);
+ ttEach(this.first(), function(t) {
+ success = t.select($el);
+ });
+ return success;
+ },
+ autocomplete: function autocomplete(el) {
+ var success = false, $el = $(el);
+ ttEach(this.first(), function(t) {
+ success = t.autocomplete($el);
+ });
+ return success;
+ },
+ moveCursor: function moveCursoe(delta) {
+ var success = false;
+ ttEach(this.first(), function(t) {
+ success = t.moveCursor(delta);
+ });
+ return success;
+ },
+ val: function val(newVal) {
+ var query;
+ if (!arguments.length) {
+ ttEach(this.first(), function(t) {
+ query = t.getVal();
+ });
+ return query;
+ } else {
+ ttEach(this, function(t) {
+ t.setVal(newVal);
+ });
+ return this;
+ }
+ },
+ destroy: function destroy() {
+ ttEach(this, function(typeahead, $input) {
+ revert($input);
+ typeahead.destroy();
+ });
+ return this;
+ }
+ };
+ $.fn.typeahead = function(method) {
+ if (methods[method]) {
+ return methods[method].apply(this, [].slice.call(arguments, 1));
+ } else {
+ return methods.initialize.apply(this, arguments);
+ }
+ };
+ $.fn.typeahead.noConflict = function noConflict() {
+ $.fn.typeahead = old;
+ return this;
+ };
+ function ttEach($els, fn) {
+ $els.each(function() {
+ var $input = $(this), typeahead;
+ (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
+ });
+ }
+ function buildHintFromInput($input, www) {
+ return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({
+ autocomplete: "off",
+ spellcheck: "false",
+ tabindex: -1
+ });
+ }
+ function prepInput($input, www) {
+ $input.data(keys.attrs, {
+ dir: $input.attr("dir"),
+ autocomplete: $input.attr("autocomplete"),
+ spellcheck: $input.attr("spellcheck"),
+ style: $input.attr("style")
+ });
+ $input.addClass(www.classes.input).attr({
+ autocomplete: "off",
+ spellcheck: false
+ });
+ try {
+ !$input.attr("dir") && $input.attr("dir", "auto");
+ } catch (e) {}
+ return $input;
+ }
+ function getBackgroundStyles($el) {
+ return {
+ backgroundAttachment: $el.css("background-attachment"),
+ backgroundClip: $el.css("background-clip"),
+ backgroundColor: $el.css("background-color"),
+ backgroundImage: $el.css("background-image"),
+ backgroundOrigin: $el.css("background-origin"),
+ backgroundPosition: $el.css("background-position"),
+ backgroundRepeat: $el.css("background-repeat"),
+ backgroundSize: $el.css("background-size")
+ };
+ }
+ function revert($input) {
+ var www, $wrapper;
+ www = $input.data(keys.www);
+ $wrapper = $input.parent().filter(www.selectors.wrapper);
+ _.each($input.data(keys.attrs), function(val, key) {
+ _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
+ });
+ $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);
+ if ($wrapper.length) {
+ $input.detach().insertAfter($wrapper);
+ $wrapper.remove();
+ }
+ }
+ function $elOrNull(obj) {
+ var isValid, $el;
+ isValid = _.isJQuery(obj) || _.isElement(obj);
+ $el = isValid ? $(obj).first() : [];
+ return $el.length ? $el : null;
+ }
+ })();
+}); \ No newline at end of file
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tablefilter.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tablefilter.py
index 9d15bcff0..65454e140 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tablefilter.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tablefilter.py
@@ -286,7 +286,7 @@ class TableFilterMap(object):
def to_json(self, queryset):
data = {}
- for filter_name, table_filter in self.__filters.iteritems():
+ for filter_name, table_filter in self.__filters.items():
data[filter_name] = table_filter.to_json()
return data
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py
index 2cc2f4eb7..e2d23c1e8 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py
@@ -22,7 +22,7 @@
from toastergui.widgets import ToasterTable
from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project
from orm.models import CustomImageRecipe, Package, Target, Build, LogMessage, Task
-from orm.models import CustomImagePackage
+from orm.models import CustomImagePackage, Package_DependencyManager
from django.db.models import Q, Max, Sum, Count, When, Case, Value, IntegerField
from django.conf.urls import url
from django.core.urlresolvers import reverse, resolve
@@ -114,28 +114,37 @@ class LayersTable(ToasterTable):
git_url_template = '''
<a href="{% url 'layerdetails' extra.pid data.id %}">
+ {% if data.layer.local_source_dir %}
+ <code>{{data.layer.local_source_dir}}</code>
+ {% else %}
<code>{{data.layer.vcs_url}}</code>
</a>
+ {% endif %}
{% if data.get_vcs_link_url %}
<a target="_blank" href="{{ data.get_vcs_link_url }}">
- <i class="icon-share get-info"></i>
+ <span class="glyphicon glyphicon-new-window"></span>
</a>
{% endif %}
'''
- self.add_column(title="Git repository URL",
- help_text="The Git repository for the layer source code",
+ self.add_column(title="Layer source code location",
+ help_text="A Git repository or an absolute path to a directory",
hidden=True,
static_data_name="layer__vcs_url",
static_data_template=git_url_template)
git_dir_template = '''
+ {% if data.layer.local_source_dir %}
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.layer.name}} is not in a Git repository, so there is no subdirectory associated with it"> </span>
+ {% else %}
<a href="{% url 'layerdetails' extra.pid data.id %}">
<code>{{data.dirpath}}</code>
</a>
+ {% endif %}
{% if data.dirpath and data.get_vcs_dirpath_link_url %}
<a target="_blank" href="{{ data.get_vcs_dirpath_link_url }}">
- <i class="icon-share get-info"></i>
+ <span class="glyphicon glyphicon-new-window"></span>
</a>
{% endif %}'''
@@ -146,16 +155,14 @@ class LayersTable(ToasterTable):
static_data_template=git_dir_template)
revision_template = '''
- {% load projecttags %}
- {% with vcs_ref=data.get_vcs_reference %}
- {% if vcs_ref|is_shaid %}
- <a class="btn" data-content="<ul class='unstyled'> <li>{{vcs_ref}}</li> </ul>">
- {{vcs_ref|truncatechars:10}}
- </a>
+ {% if data.layer.local_source_dir %}
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.layer.name}} is not in a Git repository, so there is no revision associated with it"> </span>
{% else %}
- {{vcs_ref}}
- {% endif %}
+ {% with vcs_ref=data.get_vcs_reference %}
+ {% include 'snippets/gitrev_popover.html' %}
{% endwith %}
+ {% endif %}
'''
self.add_column(title="Git revision",
@@ -166,8 +173,8 @@ class LayersTable(ToasterTable):
deps_template = '''
{% with ods=data.dependencies.all%}
{% if ods.count %}
- <a class="btn" title="<a href='{% url "layerdetails" extra.pid data.id %}'>{{data.layer.name}}</a> dependencies"
- data-content="<ul class='unstyled'>
+ <a class="btn btn-default" title="<a href='{% url "layerdetails" extra.pid data.id %}'>{{data.layer.name}}</a> dependencies"
+ data-content="<ul class='list-unstyled'>
{% for i in ods%}
<li><a href='{% url "layerdetails" extra.pid i.depends_on.pk %}'>{{i.depends_on.layer.name}}</a></li>
{% endfor %}
@@ -190,24 +197,13 @@ class LayersTable(ToasterTable):
static_data_name="add-del-layers",
static_data_template='{% include "layer_btn.html" %}')
- project = Project.objects.get(pk=kwargs['pid'])
- self.add_column(title="LayerDetailsUrl",
- displayable = False,
- field_name="layerdetailurl",
- computation = lambda x: reverse('layerdetails', args=(project.id, x.id)))
-
- self.add_column(title="name",
- displayable = False,
- field_name="name",
- computation = lambda x: x.layer.name)
-
class MachinesTable(ToasterTable):
"""Table of Machines in Toaster"""
def __init__(self, *args, **kwargs):
super(MachinesTable, self).__init__(*args, **kwargs)
- self.empty_state = "No machines maybe you need to do a build?"
+ self.empty_state = "Toaster has no machine information for this project. Sadly, machine information cannot be obtained from builds, so this page will remain empty."
self.title = "Compatible machines"
self.default_orderby = "name"
@@ -275,7 +271,7 @@ class MachinesTable(ToasterTable):
field_name="layer_version__get_vcs_reference")
machine_file_template = '''<code>conf/machine/{{data.name}}.conf</code>
- <a href="{{data.get_vcs_machine_file_link_url}}" target="_blank"><i class="icon-share get-info"></i></a>'''
+ <a href="{{data.get_vcs_machine_file_link_url}}" target="_blank"><span class="glyphicon glyphicon-new-window"></i></a>'''
self.add_column(title="Machine file",
hidden=True,
@@ -318,7 +314,11 @@ class LayerMachinesTable(MachinesTable):
self.add_column(title="Description",
field_name="description")
- select_btn_template = '<a href="{% url "project" extra.pid %}?setMachine={{data.name}}" class="btn btn-block select-machine-btn" {% if extra.in_prj == 0%}disabled="disabled"{%endif%}>Select machine</a>'
+ select_btn_template = '''
+ <a href="{% url "project" extra.pid %}?setMachine={{data.name}}"
+ class="btn btn-default btn-block select-machine-btn
+ {% if extra.in_prj == 0%}disabled{%endif%}">Select machine</a>
+ '''
self.add_column(title="Select machine",
static_data_name="add-del-layers",
@@ -330,10 +330,10 @@ class RecipesTable(ToasterTable):
def __init__(self, *args, **kwargs):
super(RecipesTable, self).__init__(*args, **kwargs)
- self.empty_state = "Toaster has no recipe information. To generate recipe information you can configure a layer source then run a build."
+ self.empty_state = "Toaster has no recipe information. To generate recipe information you need to run a build."
build_col = { 'title' : "Build",
- 'help_text' : "Add or delete recipes to and from your project",
+ 'help_text' : "Before building a recipe, you might need to add the corresponding layer to your project",
'hideable' : False,
'filter_name' : "in_current_project",
'static_data_name' : "add-del-layers",
@@ -344,8 +344,7 @@ class RecipesTable(ToasterTable):
context = super(RecipesTable, self).get_context_data(**kwargs)
context['project'] = project
-
- context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project']))
+ context['projectlayers'] = [player.layercommit.id for player in ProjectLayer.objects.filter(project=context['project'])]
return context
@@ -395,7 +394,7 @@ class RecipesTable(ToasterTable):
recipe_file_template = '''
<code>{{data.file_path}}</code>
<a href="{{data.get_vcs_recipe_file_link_url}}" target="_blank">
- <i class="icon-share get-info"></i>
+ <span class="glyphicon glyphicon-new-window"></i>
</a>
'''
@@ -428,9 +427,19 @@ class RecipesTable(ToasterTable):
orderable=True,
field_name="license")
+ revision_link_template = '''
+ {% if data.layer_version.layer.local_source_dir %}
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.layer_version.layer.name}} is not in a Git repository, so there is no revision associated with it"> </span>
+ {% else %}
+ {{data.layer_version.get_vcs_reference}}
+ {% endif %}
+ '''
+
self.add_column(title="Git revision",
hidden=True,
- field_name="layer_version__get_vcs_reference")
+ static_data_name="layer_version__get_vcs_reference",
+ static_data_template=revision_link_template)
class LayerRecipesTable(RecipesTable):
@@ -466,7 +475,11 @@ class LayerRecipesTable(RecipesTable):
self.add_column(title="Description",
field_name="get_description_or_summary")
- build_recipe_template ='<button class="btn btn-block build-recipe-btn" data-recipe-name="{{data.name}}" {%if extra.in_prj == 0 %}disabled="disabled"{%endif%}>Build recipe</button>'
+ build_recipe_template = '''
+ <a class="btn btn-default btn-block build-recipe-btn
+ {% if extra.in_prj == 0 %}disabled{% endif %}"
+ data-recipe-name="{{data.name}}">Build recipe</a>
+ '''
self.add_column(title="Build recipe",
static_data_name="add-del-layers",
@@ -481,7 +494,16 @@ class CustomImagesTable(ToasterTable):
def get_context_data(self, **kwargs):
context = super(CustomImagesTable, self).get_context_data(**kwargs)
+
+ empty_state_template = '''
+ You have not created any custom images yet.
+ <a href="{% url 'newcustomimage' data.pid %}">
+ Create your first custom image</a>
+ '''
+ context['empty_state'] = self.render_static_data(empty_state_template,
+ kwargs)
project = Project.objects.get(pk=kwargs['pid'])
+
# TODO put project into the ToasterTable base class
context['project'] = project
return context
@@ -507,29 +529,31 @@ class CustomImagesTable(ToasterTable):
static_data_template=name_link_template)
recipe_file_template = '''
+ {% if data.get_base_recipe_file %}
<code>{{data.name}}_{{data.version}}.bb</code>
- <a href="{% url 'customrecipedownload' extra.pid data.pk %}">
- <i class="icon-download-alt" data-original-title="Download recipe
- file"></i>
- </a>'''
+ <a href="{% url 'customrecipedownload' extra.pid data.pk %}"
+ class="glyphicon glyphicon-download-alt get-help" title="Download recipe file"></a>
+ {% endif %}'''
self.add_column(title="Recipe file",
static_data_name='recipe_file_download',
static_data_template=recipe_file_template)
approx_packages_template = '''
+ {% if data.get_all_packages.count > 0 %}
<a href="{% url 'customrecipe' extra.pid data.id %}">
{{data.get_all_packages.count}}
- </a>'''
+ </a>
+ {% endif %}'''
- self.add_column(title="Approx packages",
+ self.add_column(title="Packages",
static_data_name='approx_packages',
static_data_template=approx_packages_template)
build_btn_template = '''
<button data-recipe-name="{{data.name}}"
- class="btn btn-block build-recipe-btn" style="margin-top: 5px;" >
+ class="btn btn-default btn-block build-recipe-btn">
Build
</button>'''
@@ -695,6 +719,7 @@ class PackagesTable(ToasterTable):
def setup_queryset(self, *args, **kwargs):
recipe = Recipe.objects.get(pk=kwargs['recipe_id'])
+ self.static_context_extra['target_name'] = recipe.name
self.queryset = self.create_package_list(recipe, kwargs['pid'])
self.queryset = self.queryset.order_by('name')
@@ -711,13 +736,15 @@ class PackagesTable(ToasterTable):
self.add_column(title="Approx Size",
orderable=True,
+ field_name="size",
static_data_name="size",
static_data_template="{% load projecttags %} \
{{data.size|filtered_filesizeformat}}")
self.add_column(title="License",
field_name="license",
- orderable=True)
+ orderable=True,
+ hidden=True)
self.add_column(title="Dependencies",
@@ -764,7 +791,19 @@ class SelectPackagesTable(PackagesTable):
self.queryset = self.queryset.order_by('name')
+ # This target is the target used to work out which group of dependences
+ # to display, if we've built the custom image we use it otherwise we
+ # can use the based recipe instead
+ if prj.build_set.filter(target__target=self.cust_recipe.name).count()\
+ > 0:
+ self.static_context_extra['target_name'] = self.cust_recipe.name
+ else:
+ self.static_context_extra['target_name'] =\
+ Package_DependencyManager.TARGET_LATEST
+
self.static_context_extra['recipe_id'] = kwargs['custrecipeid']
+
+
self.static_context_extra['current_packages'] = \
current_packages.values_list('pk', flat=True)
@@ -860,26 +899,22 @@ class ProjectsTable(ToasterTable):
last_activity_on_template = '''
{% load project_url_tag %}
<span data-project-field="updated">
- <a href="{% project_url data %}">
{{data.updated | date:"d/m/y H:i"}}
- </a>
</span>
'''
release_template = '''
<span data-project-field="release">
{% if data.release %}
- <a href="{% url 'project' data.id %}#project-details">
- {{data.release.name}}
- </a>
+ {{data.release.name}}
{% elif data.is_default %}
- <span class="muted">Not applicable</span>
- <i class="icon-question-sign get-help hover-help"
- data-original-title="This project does not have a release set.
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help hover-help"
+ title="This project does not have a release set.
It simply collects information about the builds you start from
the command line while Toaster is running"
style="visibility: hidden;">
- </i>
+ </span>
{% else %}
No release available
{% endif %}
@@ -889,16 +924,14 @@ class ProjectsTable(ToasterTable):
machine_template = '''
<span data-project-field="machine">
{% if data.is_default %}
- <span class="muted">Not applicable</span>
- <i class="icon-question-sign get-help hover-help"
- data-original-title="This project does not have a machine
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help hover-help"
+ title="This project does not have a machine
set. It simply collects information about the builds you
start from the command line while Toaster is running"
- style="visibility: hidden;"></i>
+ style="visibility: hidden;"></span>
{% else %}
- <a href="{% url 'project' data.id %}#machine-distro">
- {{data.get_current_machine_name}}
- </a>
+ {{data.get_current_machine_name}}
{% endif %}
</span>
'''
@@ -908,20 +941,16 @@ class ProjectsTable(ToasterTable):
<a href="{% url 'projectbuilds' data.id %}">
{{data.get_number_of_builds}}
</a>
- {% else %}
- <span class="muted">0</span>
{% endif %}
'''
last_build_outcome_template = '''
{% if data.get_number_of_builds > 0 %}
- <a href="{% url 'builddashboard' data.get_last_build_id %}">
- {% if data.get_last_outcome == extra.Build.SUCCEEDED %}
- <i class="icon-ok-sign success"></i>
- {% elif data.get_last_outcome == extra.Build.FAILED %}
- <i class="icon-minus-sign error"></i>
- {% endif %}
- </a>
+ {% if data.get_last_outcome == extra.Build.SUCCEEDED %}
+ <span class="glyphicon glyphicon-ok-circle"></span>
+ {% elif data.get_last_outcome == extra.Build.FAILED %}
+ <span class="glyphicon glyphicon-minus-sign"></span>
+ {% endif %}
{% endif %}
'''
@@ -935,7 +964,7 @@ class ProjectsTable(ToasterTable):
errors_template = '''
{% if data.get_number_of_builds > 0 and data.get_last_errors > 0 %}
- <a class="errors.count error"
+ <a class="errors.count text-danger"
href="{% url "builddashboard" data.get_last_build_id %}#errors">
{{data.get_last_errors}} error{{data.get_last_errors | pluralize}}
</a>
@@ -944,7 +973,7 @@ class ProjectsTable(ToasterTable):
warnings_template = '''
{% if data.get_number_of_builds > 0 and data.get_last_warnings > 0 %}
- <a class="warnings.count warning"
+ <a class="warnings.count text-warning"
href="{% url "builddashboard" data.get_last_build_id %}#warnings">
{{data.get_last_warnings}} warning{{data.get_last_warnings | pluralize}}
</a>
@@ -953,9 +982,7 @@ class ProjectsTable(ToasterTable):
image_files_template = '''
{% if data.get_number_of_builds > 0 and data.get_last_outcome == extra.Build.SUCCEEDED %}
- <a href="{% url "builddashboard" data.get_last_build_id %}#images">
- {{data.get_last_build_extensions}}
- </a>
+ {{data.get_last_build_extensions}}
{% endif %}
'''
@@ -991,7 +1018,7 @@ class ProjectsTable(ToasterTable):
static_data_name='machine',
static_data_template=machine_template)
- self.add_column(title='Number of builds',
+ self.add_column(title='Builds',
help_text='The number of builds which have been run \
for the project',
hideable=False,
@@ -1121,19 +1148,17 @@ class BuildsTable(ToasterTable):
def setup_columns(self, *args, **kwargs):
outcome_template = '''
- <a href="{% url "builddashboard" data.id %}">
- {% if data.outcome == data.SUCCEEDED %}
- <i class="icon-ok-sign success"></i>
- {% elif data.outcome == data.FAILED %}
- <i class="icon-minus-sign error"></i>
- {% endif %}
- </a>
+ {% if data.outcome == data.SUCCEEDED %}
+ <span class="glyphicon glyphicon-ok-circle"></span>
+ {% elif data.outcome == data.FAILED %}
+ <span class="glyphicon glyphicon-minus-sign"></span>
+ {% endif %}
{% if data.cooker_log_path %}
&nbsp;
<a href="{% url "build_artifact" data.id "cookerlog" data.id %}">
- <i class="icon-download-alt get-help"
- data-original-title="Download build log"></i>
+ <span class="glyphicon glyphicon-download-alt get-help"
+ data-original-title="Download build log"></span>
</a>
{% endif %}
'''
@@ -1148,45 +1173,39 @@ class BuildsTable(ToasterTable):
'''
machine_template = '''
- <a href="{% url "builddashboard" data.id %}">
- {{data.machine}}
- </a>
+ {{data.machine}}
'''
started_on_template = '''
- <a href="{% url "builddashboard" data.id %}">
- {{data.started_on | date:"d/m/y H:i"}}
- </a>
+ {{data.started_on | date:"d/m/y H:i"}}
'''
completed_on_template = '''
- <a href="{% url "builddashboard" data.id %}">
- {{data.completed_on | date:"d/m/y H:i"}}
- </a>
+ {{data.completed_on | date:"d/m/y H:i"}}
'''
failed_tasks_template = '''
{% if data.failed_tasks.count == 1 %}
- <a href="{% url "task" data.id data.failed_tasks.0.id %}">
- <span class="error">
- {{data.failed_tasks.0.recipe.name}}.{{data.failed_tasks.0.task_name}}
+ <a class="text-danger" href="{% url "task" data.id data.failed_tasks.0.id %}">
+ <span>
+ {{data.failed_tasks.0.recipe.name}} {{data.failed_tasks.0.task_name}}
</span>
</a>
<a href="{% url "build_artifact" data.id "tasklogfile" data.failed_tasks.0.id %}">
- <i class="icon-download-alt"
- data-original-title="Download task log file">
- </i>
+ <span class="glyphicon glyphicon-download-alt get-help"
+ title="Download task log file">
+ </span>
</a>
{% elif data.failed_tasks.count > 1 %}
<a href="{% url "tasks" data.id %}?filter=outcome%3A{{extra.Task.OUTCOME_FAILED}}">
- <span class="error">{{data.failed_tasks.count}} tasks</span>
+ <span class="text-danger">{{data.failed_tasks.count}} tasks</span>
</a>
{% endif %}
'''
errors_template = '''
{% if data.errors_no %}
- <a class="errors.count error" href="{% url "builddashboard" data.id %}#errors">
+ <a class="errors.count text-danger" href="{% url "builddashboard" data.id %}#errors">
{{data.errors_no}} error{{data.errors_no|pluralize}}
</a>
{% endif %}
@@ -1194,7 +1213,7 @@ class BuildsTable(ToasterTable):
warnings_template = '''
{% if data.warnings_no %}
- <a class="warnings.count warning" href="{% url "builddashboard" data.id %}#warnings">
+ <a class="warnings.count text-warning" href="{% url "builddashboard" data.id %}#warnings">
{{data.warnings_no}} warning{{data.warnings_no|pluralize}}
</a>
{% endif %}
@@ -1202,16 +1221,18 @@ class BuildsTable(ToasterTable):
time_template = '''
{% load projecttags %}
- <a href="{% url "buildtime" data.id %}">
+ {% if data.outcome == extra.Build.SUCCEEDED %}
+ <a href="{% url "buildtime" data.id %}">
+ {{data.timespent_seconds | sectohms}}
+ </a>
+ {% else %}
{{data.timespent_seconds | sectohms}}
- </a>
+ {% endif %}
'''
image_files_template = '''
{% if data.outcome == extra.Build.SUCCEEDED %}
- <a href="{% url "builddashboard" data.id %}#images">
{{data.get_image_file_extensions}}
- </a>
{% endif %}
'''
@@ -1429,10 +1450,10 @@ class AllBuildsTable(BuildsTable):
{{data.project.name}}
</a>
{% if data.project.is_default %}
- <i class="icon-question-sign get-help hover-help" title=""
+ <span class="glyphicon glyphicon-question-sign get-help hover-help" title=""
data-original-title="This project shows information about
the builds you start from the command line while Toaster is
- running" style="visibility: hidden;"></i>
+ running" style="visibility: hidden;"></span>
{% endif %}
'''
@@ -1482,7 +1503,6 @@ class ProjectBuildsTable(BuildsTable):
"""
self.project_id = kwargs['pid']
super(ProjectBuildsTable, self).setup_queryset(*args, **kwargs)
-
project = Project.objects.get(pk=self.project_id)
self.queryset = self.queryset.filter(project=project)
@@ -1496,8 +1516,23 @@ class ProjectBuildsTable(BuildsTable):
self.project_id = kwargs['pid']
context = super(ProjectBuildsTable, self).get_context_data(**kwargs)
+ empty_state_template = '''
+ This project has no builds.
+ <a href="{% url 'projectimagerecipes' data.pid %}">
+ Choose a recipe to build</a>
+ '''
+ context['empty_state'] = self.render_static_data(empty_state_template,
+ kwargs)
+
project = Project.objects.get(pk=self.project_id)
context['mru'] = Build.get_recent(project)
context['project'] = project
+ self.setup_queryset(**kwargs)
+ if self.queryset.count() == 0 and \
+ project.build_set.filter(outcome=Build.IN_PROGRESS).count() > 0:
+ context['build_in_progress_none_completed'] = True
+ else:
+ context['build_in_progress_none_completed'] = False
+
return context
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/base.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/base.html
index 210cf3360..496dd6eab 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/base.html
@@ -8,9 +8,8 @@
{% block title %} Toaster {% endblock %}
</title>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css"/>
- <link rel="stylesheet" href="{% static 'css/bootstrap-responsive.min.css' %}" type='text/css'/>
+ <!--link rel="stylesheet" href="{% static 'css/bootstrap-theme.css' %}" type="text/css"/-->
<link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}" type='text/css'/>
- <link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'/>
<link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -21,6 +20,10 @@
</script>
<script src="{% static 'js/bootstrap.min.js' %}">
</script>
+ <script src="{% static 'js/typeahead.jquery.js' %}">
+ </script>
+ <script src="{% static 'js/jsrender.min.js' %}">
+ </script>
<script src="{% static 'js/prettify.js' %}">
</script>
<script src="{% static 'js/libtoaster.js' %}">
@@ -31,6 +34,8 @@
</script>
{% endif %}
<script>
+ $.views.settings.delimiters("<%", "%>");
+
libtoaster.ctx = {
jsUrl : "{% static 'js/' %}",
htmlUrl : "{% static 'html/' %}",
@@ -39,6 +44,7 @@
{% if project.id %}
projectId : {{project.id}},
projectPageUrl : {% url 'project' project.id as purl %}{{purl|json}},
+ xhrProjectUrl : {% url 'xhr_project' project.id as pxurl %}{{pxurl|json}},
projectName : {{project.name|json}},
recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}},
layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}},
@@ -47,7 +53,9 @@
xhrCustomRecipeUrl : "{% url 'xhr_customrecipe' %}",
projectId : {{project.id}},
xhrBuildRequestUrl: "{% url 'xhr_buildrequest' project.id %}",
+ mostRecentBuildsUrl: "{% url 'most_recent_builds' %}?project_id={{project.id}}",
{% else %}
+ mostRecentBuildsUrl: "{% url 'most_recent_builds' %}",
projectId : undefined,
projectPageUrl : undefined,
projectName : undefined,
@@ -58,69 +66,72 @@
{% endblock %}
</head>
- <body style="height: 100%">
+ <body>
{% csrf_token %}
- <div id="loading-notification" class="alert lead text-center" style="display:none">
+ <div id="loading-notification" class="alert alert-warning lead text-center" style="display:none">
Loading <i class="fa-pulse icon-spinner"></i>
</div>
- <div id="change-notification" class="alert lead alert-info" style="display:none">
- <button type="button" class="close" id="hide-alert">&times;</button>
+ <div id="change-notification" class="alert alert-info alert-dismissible change-notification" style="display:none">
+ <button type="button" class="close" id="hide-alert" data-toggle="alert">&times;</button>
<span id="change-notification-msg"></span>
</div>
- <div class="navbar navbar-fixed-top">
- <div class="navbar-inner">
- <div class="container-fluid">
- <a class="brand logo" href="#"><img src="{% static 'img/logo.png' %}" class="" alt="Yocto logo project"/></a>
- <span class="brand">
- <a href="/">Toaster</a>
+ <nav class="navbar navbar-default navbar-fixed-top">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#global-nav" aria-expanded="false">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <div class="toaster-navbar-brand">
+ <a href="/">
+ <img class="logo" src="{% static 'img/logo.png' %}" class="" alt="Yocto logo project"/>
+ </a>
+ <a class="brand" href="/">Toaster</a>
{% if DEBUG %}
- <i class="icon-info-sign" title="<strong>Toaster version information</strong>" data-content="<dl><dt>Git branch</dt><dd>{{TOASTER_BRANCH}}</dd><dt>Git revision</dt><dd>{{TOASTER_REVISION}}</dd></dl>"></i>
+ <span class="glyphicon glyphicon-info-sign" title="<strong>Toaster version information</strong>" data-content="<dl><dt>Git branch</dt><dd>{{TOASTER_BRANCH}}</dd><dt>Git revision</dt><dd>{{TOASTER_REVISION}}</dd></dl>"></i>
{% endif %}
- </span>
- {% if request.resolver_match.url_name != 'landing' and request.resolver_match.url_name != 'newproject' %}
- <ul class="nav">
- <li {% if request.resolver_match.url_name == 'all-builds' %}
- class="active"
- {% endif %}>
+ </div>
+ </div>
+ <div class="collapse navbar-collapse" id="global-nav">
+ <ul class="nav navbar-nav">
+ {% if request.resolver_match.url_name != 'landing' and request.resolver_match.url_name != 'newproject' %}
+ <li {% if request.resolver_match.url_name == 'all-builds' %}
+ class="active"
+ {% endif %}>
<a href="{% url 'all-builds' %}">
- <i class="icon-tasks"></i>
+ <i class="glyphicon glyphicon-tasks"></i>
All builds
</a>
- </li>
- <li {% if request.resolver_match.url_name == 'all-projects' %}
- class="active"
- {% endif %}>
+ </li>
+ <li {% if request.resolver_match.url_name == 'all-projects' %}
+ class="active"
+ {% endif %}>
<a href="{% url 'all-projects' %}">
<i class="icon-folder-open"></i>
All projects
</a>
- </li>
- </ul>
- {% endif %}
- <ul class="nav pull-right">
- <li>
+ </li>
+ {% endif %}
+ <li>
<a target="_blank" href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html">
- <i class="icon-book"></i>
- Manual
+ <i class="glyphicon glyphicon-book"></i>
+ Documentation
</a>
- </li>
- </ul>
- <span class="pull-right divider-vertical"></span>
- <div class="btn-group pull-right">
- <a class="btn" id="new-project-button" href="{% url 'newproject' %}">New project</a>
+ </li>
+ </ul>
+ <a class="btn btn-default navbar-btn navbar-right" id="new-project-button" href="{% url 'newproject' %}">New project</a>
</div>
- </div>
</div>
- </div>
+ </nav>
- <div class="container-fluid top-padded">
- <div class="row-fluid">
- {% block pagecontent %}
- {% endblock %}
- </div>
+ <div class="container-fluid">
+ {% block pagecontent %}
+ {% endblock %}
</div>
</body>
</html>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html
index a62e0b1cb..4d5066732 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html
@@ -3,30 +3,29 @@
{% load humanize %}
{% block pagecontent %}
-<div class="row-fluid">
-<!-- Breadcrumbs -->
- <div class="section">
- <ul class="breadcrumb" id="breadcrumb">
- <li><a href="{% project_url build.project %}">{{build.project.name}}</a></li>
- {% if not build.project.is_default %}
- <li><a href="{% url 'projectbuilds' build.project.id %}">Builds</a></li>
- {% endif %}
- <li><a href="{%url 'builddashboard' build.pk%}">{{build.get_sorted_target_list.0.target}} {%if build.target_set.all.count > 1%}(+{{build.target_set.all.count|add:"-1"}}){%endif%} {{build.machine}} ({{build.completed_on|date:"d/m/y H:i"}})</a></li>
- {% block localbreadcrumb %}{% endblock %}
- </ul>
- <script>
- $( function () {
- $('#breadcrumb > li').append('<span class="divider">&rarr;</span>');
- $('#breadcrumb > li:last').addClass("active");
- $('#breadcrumb > li:last > span').remove();
- });
- </script>
- </div> <!--section-->
-
- <!-- Begin container -->
- {% block pagedetailinfomain %}{% endblock %}
- <!-- End container -->
-
+<div class="row">
+ <!-- Breadcrumbs -->
+ <div class="col-md-12">
+ <ul class="breadcrumb" id="breadcrumb">
+ <li><a href="{% project_url build.project %}">{{build.project.name}}</a></li>
+ {% if not build.project.is_default %}
+ <li><a href="{% url 'projectbuilds' build.project.id %}">Builds</a></li>
+ {% endif %}
+ <li><a href="{%url 'builddashboard' build.pk%}">{{build.get_sorted_target_list.0.target}} {%if build.target_set.all.count > 1%}(+{{build.target_set.all.count|add:"-1"}}){%endif%} {{build.machine}} ({{build.completed_on|date:"d/m/y H:i"}})</a></li>
+ {% block localbreadcrumb %}{% endblock %}
+ </ul>
+ <script>
+$( function () {
+ $('#breadcrumb > li').append('<span class="divider">&rarr;</span>');
+ $('#breadcrumb > li:last').addClass("active");
+ $('#breadcrumb > li:last > span').remove();
+ });
+ </script>
+ </div>
</div>
+<!-- Begin container -->
+{% block pagedetailinfomain %}{% endblock %}
+<!-- End container -->
+
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuildpage.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
index 0d8c8820d..f5eee9651 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
@@ -3,9 +3,95 @@
{% load project_url_tag %}
{% load objects_to_dictionaries_filter %}
{% load humanize %}
+{% load field_values_filter %}
{% block pagecontent %}
+
+ <script>
+ var configVarUrl = "{% url 'configvars' build.id %}";
+
+ $(document).ready(function(){
+
+ $("#delete-build-confirm").click(function(){
+ libtoaster.disableAjaxLoadingTimer();
+ $(this).find('[data-role="submit-state"]').hide();
+ $(this).find('[data-role="loading-state"]').show();
+ $(this).attr("disabled", "disabled");
+
+ /* Make the modal non cancelable while delete is in progress */
+ $('#delete-build-modal button[data-dismiss="modal"]').hide();
+
+ $.ajax({
+ type: 'DELETE',
+ url: "{% url 'xhr_build' build.id %}",
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function (data) {
+ if (data.error !== "ok") {
+ console.warn(data.error);
+ } else {
+ libtoaster.setNotification("build-deleted",
+ $("#deleted-build-message").html());
+ window.location.replace(data.gotoUrl);
+ }
+ },
+ error: function (data) {
+ console.warn(data);
+ }
+ });
+ });
+
+
+ $('#breadcrumb > li').append('<span class="divider">&rarr;</span>');
+ $('#breadcrumb > li:last').addClass("active");
+ $('#breadcrumb > li:last > span').remove();
+
+ $("#build-menu li a").each(function(){
+ /* Set the page active state in the Build menu */
+ var currentUrl = window.location.href.split('?')[0];
+ if (currentUrl === $(this).prop("href")){
+ $(this).parent().addClass("active");
+ } else {
+ /* Special case the configvar as this is part of configuration
+ * page but is a separate url
+ */
+ if (window.location.pathname === configVarUrl){
+ $("#menu-configuration").addClass("active");
+ } else {
+ $(this).parent().removeClass("active");
+ }
+ }
+ });
+ });
+ </script>
+
+<span style="display:none" id="deleted-build-message">
+ You have deleted 1 build: <strong>{{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}}</strong> completed on <strong>{{build.completed_on|date:"d/m/y H:i"}}</strong>
+</span>
+
+<div class="modal fade" tabindex="-1" role="dialog" id="delete-build-modal" style="display: none;" data-backdrop="static" data-keyboard="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-body">
+ <p>Are you sure you want to delete the build <strong>{{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}}</strong> completed on <strong>{{build.completed_on|date:"d/m/y H:i"}}</strong>?</p>
+ </div>
+ <div class="modal-footer">
+ <button id="delete-build-confirm" class="btn btn-primary btn-large">
+ <span data-role="submit-state">Delete build</span>
+ <span data-role="loading-state" style="display:none">
+ <span class="fa-pulse">
+ <i class="icon-spinner"></i>
+ </span>
+ &nbsp;Deleting build...
+ </span>
+ </button>
+ <button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button>
+ </div>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div> <!-- / modal -->
+
+<div class="row">
<!-- breadcrumbs -->
- <div class="section">
+ <div class="col-md-12">
<ul class="breadcrumb" id="breadcrumb">
<li><a href="{% project_url build.project %}">{{build.project.name}}</a></li>
{% if not build.project.is_default %}
@@ -20,73 +106,56 @@
</li>
{% block localbreadcrumb %}{% endblock %}
</ul>
- <script>
- $( function () {
- $('#breadcrumb > li').append('<span class="divider">&rarr;</span>');
- $('#breadcrumb > li:last').addClass("active");
- $('#breadcrumb > li:last > span').remove();
- });
- </script>
</div>
+</div>
- <div class="row-fluid">
- <!-- begin left sidebar container -->
- <div id="nav" class="span2">
- <ul class="nav nav-list well">
- <li
- {% if request.resolver_match.url_name == 'builddashboard' %}
- class="active"
- {% endif %} >
- <a class="nav-parent" href="{% url 'builddashboard' build.pk %}">Build summary</a>
- </li>
- {% if build.target_set.all.0.is_image and build.outcome == 0 %}
- <li class="nav-header">Images</li>
- {% block nav-target %}
- {% for t in build.get_sorted_target_list %}
- <li><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li>
- {% endfor %}
- {% endblock %}
- {% endif %}
- <li class="nav-header">Build</li>
- {% block nav-configuration %}
- <li><a href="{% url 'configuration' build.pk %}">Configuration</a></li>
- {% endblock %}
- {% block nav-tasks %}
- <li><a href="{% url 'tasks' build.pk %}">Tasks</a></li>
- {% endblock %}
- {% block nav-recipes %}
- <li><a href="{% url 'recipes' build.pk %}">Recipes</a></li>
- {% endblock %}
- {% block nav-packages %}
- <li><a href="{% url 'packages' build.pk %}">Packages</a></li>
- {% endblock %}
- <li class="nav-header">Performance</li>
- {% block nav-buildtime %}
- <li><a href="{% url 'buildtime' build.pk %}">Time</a></li>
- {% endblock %}
- {% block nav-cputime %}
- <li><a href="{% url 'cputime' build.pk %}">CPU usage</a></li>
- {% endblock %}
- {% block nav-diskio %}
- <li><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li>
- {% endblock %}
-
- <li class="divider"></li>
+ <!-- begin left sidebar container for builds which started properly -->
+ {% if build.started %}
+ <div class="row">
+ <div id="nav" class="col-md-2">
+ <ul class="nav nav-pills nav-stacked" id="build-menu">
+ <li id="menu-dashboard"
+ {% if request.resolver_match.url_name == 'builddashboard' %}
+ class="active"
+ {% endif %} >
+ <a href="{% url 'builddashboard' build.pk %}">Build summary</a>
+ </li>
+ {% if build.has_images and build.outcome == build.SUCCEEDED %}
+ <li class="nav-header" data-menu-heading="images">Images</li>
+ {% block nav-target %}
+ {% for t in build.get_sorted_target_list %}
+ {% if t.has_images %}
+ <li id="menu-{{t.target}}"><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li>
+ {% endif %}
+ {% endfor %}
+ {% endblock %}
+ {% endif %}
+ <li class="nav-header">Build</li>
+ <li id="menu-configuration"><a href="{% url 'configuration' build.pk %}">Configuration</a></li>
+ <li><a href="{% url 'tasks' build.pk %}">Tasks</a></li>
+ <li><a href="{% url 'recipes' build.pk %}">Recipes</a></li>
+ <li><a href="{% url 'packages' build.pk %}">Packages</a></li>
+ <li class="nav-header">Performance</li>
+ <li><a href="{% url 'buildtime' build.pk %}">Time</a></li>
+ <li><a href="{% url 'cputime' build.pk %}">CPU usage</a></li>
+ <li><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li>
- <li>
- <p class="navbar-btn">
- <a class="btn btn-block" href="{% url 'build_artifact' build.id 'cookerlog' build.id %}">
- Download build log
+ <li class="nav-header">Actions</li>
+ <li>
+ <a href="{% url 'build_artifact' build.id 'cookerlog' build.id %}">
+ <span class="glyphicon glyphicon-download-alt"></span>
+ Download build log
</a>
- </p>
- </li>
+ </li>
- {% with build.get_custom_image_recipes as custom_image_recipes %}
- {% if custom_image_recipes.count > 0 %}
- <!-- edit custom image built during this build -->
- <li>
- <p class="navbar-btn" data-role="edit-custom-image-trigger">
- <button class="btn btn-block">Edit custom image</button>
+ {% with build.get_custom_image_recipes as custom_image_recipes %}
+ {% if custom_image_recipes.count > 0 %}
+ <!-- edit custom image built during this build -->
+ <li>
+ <a href="#" data-role="edit-custom-image-trigger">
+ <span class="glyphicon glyphicon-edit"></span>
+ Edit custom image
+ </a>
{% include 'editcustomimage_modal.html' %}
<script>
var editableCustomImageRecipes = {{ custom_image_recipes | objects_to_dictionaries:"id,name" | json }};
@@ -111,47 +180,55 @@
});
});
</script>
- </p>
- </li>
- {% endif %}
- {% endwith %}
-
- <li>
- <!-- new custom image from image recipe in this build -->
- <p class="navbar-btn" data-role="new-custom-image-trigger">
- <button class="btn btn-block">New custom image</button>
- </p>
- {% include 'newcustomimage_modal.html' %}
- <script>
- // imageRecipes includes both custom image recipes and built-in
- // image recipes, any of which can be used as the basis for a
- // new custom image
- var imageRecipes = {{ build.get_image_recipes | objects_to_dictionaries:"id,name" | json }};
-
- $(document).ready(function () {
- var newCustomImageModal = $('#new-custom-image-modal');
- var newCustomImageTrigger = $('[data-role="new-custom-image-trigger"]');
-
- // show create new custom image modal to select an image built
- // during this build as the basis for the custom recipe
- newCustomImageTrigger.click(function () {
- if (!imageRecipes.length) {
- return;
- }
-
- newCustomImageModalSetRecipes(imageRecipes);
- newCustomImageModal.modal('show');
- });
- });
- </script>
- </li>
- </ul>
+ </li>
+ {% endif %}
+ {% endwith %}
- </div>
- <!-- end left sidebar container -->
+ <!-- new custom image from image recipe in this build -->
+ {% if build.has_image_recipes %}
+ <li>
+ <a href="#" data-role="new-custom-image-trigger">
+ <span class="glyphicon glyphicon-plus"></span>
+ New custom image
+ </a>
+ {% include 'newcustomimage_modal.html' %}
+ <script>
+ // imageRecipes includes both custom image recipes and built-in
+ // image recipes, any of which can be used as the basis for a
+ // new custom image
+ var imageRecipes = {{ build.get_image_recipes | objects_to_dictionaries:"id,name" | json }};
- <!-- begin right container -->
- {% block buildinfomain %}{% endblock %}
- <!-- end right container -->
+ $(document).ready(function () {
+ var newCustomImageModal = $('#new-custom-image-modal');
+ var newCustomImageTrigger = $('[data-role="new-custom-image-trigger"]');
+
+ // show create new custom image modal to select an image built
+ // during this build as the basis for the custom recipe
+ newCustomImageTrigger.click(function () {
+ if (!imageRecipes.length) {
+ return;
+ }
+
+ newCustomImageModalSetRecipes(imageRecipes);
+ newCustomImageModal.modal('show');
+ });
+ });
+ </script>
+ {% endif %}
+
+ <li>
+ <a href="#delete-build-modal" id="delete-build" data-toggle="modal" data-target="#delete-build-modal" class="text-danger">
+ <span class="glyphicon glyphicon-trash"></span>
+ Delete build
+ </a>
+ </ul>
+ </div>
+ <!-- end left sidebar container -->
+ {% endif %}
+
+ <!-- right container; need class="row" for builds without left-hand menu -->
+ <div{% if not build.started %} class="row"{% endif %}>
+ {% block buildinfomain %}{% endblock %}
+ </div>
</div>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
index 8778305f3..8427d2521 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
@@ -7,24 +7,24 @@
{% block pagecontent %}
-{% include "projecttopbar.html" %}
-<script type="text/javascript">
- $(document).ready(function(){
- $("#config-nav .nav li a").each(function(){
- if (window.location.pathname === $(this).attr('href'))
- $(this).parent().addClass('active');
- else
- $(this).parent().removeClass('active');
- });
-
- $("#topbar-configuration-tab").addClass("active")
- });
-</script>
-
-<div class="row-fluid">
+<div class="row">
+ {% include "projecttopbar.html" %}
+ <script type="text/javascript">
+$(document).ready(function(){
+ $("#config-nav .nav li a").each(function(){
+ if (window.location.pathname === $(this).attr('href'))
+ $(this).parent().addClass('active');
+ else
+ $(this).parent().removeClass('active');
+ });
+
+ $("#topbar-configuration-tab").addClass("active")
+ });
+ </script>
+
<!-- only on config pages -->
- <div id="config-nav" class="span2">
- <ul class="nav nav-list well">
+ <div id="config-nav" class="col-md-2">
+ <ul class="nav nav-pills nav-stacked">
<li><a class="nav-parent" href="{% url 'project' project.id %}">Configuration</a></li>
<li class="nav-header">Compatible metadata</li>
<li><a href="{% url 'projectcustomimages' project.id %}">Custom images</a></li>
@@ -34,12 +34,18 @@
<li><a href="{% url 'projectlayers' project.id %}">Layers</a></li>
<li class="nav-header">Extra configuration</li>
<li><a href="{% url 'projectconf' project.id %}">BitBake variables</a></li>
+
+ <li class="nav-header">Actions</li>
+ <li>
+ <a href="#delete-project-modal" role="button" class="text-danger" data-toggle="modal" data-target="#delete-project-modal">
+ <i class="icon-trash text-danger"></i> Delete project</a>
+ </li>
</ul>
</div>
- <div class="span10">
+ <div class="col-md-10">
{% block projectinfomain %}{% endblock %}
</div>
-</div>
+</div>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
index ce023f51a..a2011fa90 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
@@ -2,12 +2,10 @@
</table>
<!-- Show pagination controls -->
-<div class="pagination pagination-centered">
- <div class="pull-left">
- Showing {{objects.start_index}} to {{objects.end_index}} out of {{objects.paginator.count}} entries.
- </div>
+<div id="pagination-basetable_bottom">
+ <!--span class="help-inline">Showing {{objects.start_index}} to {{objects.end_index}} out of {{objects.paginator.count}} entries.</span-->
- <ul class="pagination" style="display: block-inline">
+ <ul class="pagination">
{%if objects.has_previous %}
<li><a href="javascript:reload_params({'page':{{objects.previous_page_number}}})">&laquo;</a></li>
{%else%}
@@ -22,16 +20,18 @@
<li class="disabled"><a href="#">&raquo;</a></li>
{%endif%}
</ul>
- <div class="pull-right">
- <span class="help-inline" style="padding-top:5px;">Show rows:</span>
- <select style="margin-top:5px;margin-bottom:0px;" class="pagesize">
- {% with "10 25 50 100 150" as list%}
+ <form class="navbar-form navbar-right">
+ <div class="form-group">
+ <label>Show rows:</label>
+ <select class="form-control pagesize">
+ {% with "10 25 50 100 150" as list%}
{% for i in list.split %}
- <option value="{{i}}">{{i}}</option>
+ <option value="{{i}}">{{i}}</option>
{% endfor %}
- {% endwith %}
- </select>
- </div>
+ {% endwith %}
+ </select>
+ </div>
+ </form>
</div>
<!-- Update page display settings -->
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top.html
index 0ddd74904..5a9076d2a 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/basetable_top.html
@@ -159,66 +159,83 @@
</script>
<!-- control header -->
-<div class="navbar">
- <div class="navbar-inner">
- <form class="navbar-search input-append pull-left span6" id="searchform">
- <input id="search" name="search" type="text" placeholder="Search {%if object_search_display %}{{object_search_display}}{%else%}{{objectname}}{%endif%}" value="{%if request.GET.search %}{{request.GET.search}}{% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{%endif%}
- <input type="hidden" name="orderby" value="{{request.GET.orderby}}">
- <input type="hidden" name="page" value="1">
- <button class="btn" id="search-button" type="submit" value="Search">Search</button>
- </form>
- <div class="pull-right">
-{% if tablecols %}
- <div class="btn-group">
- <button id="edit-columns-button" class="btn dropdown-toggle" data-toggle="dropdown">Edit columns
- <span class="caret"></span>
- </button>
+<div class="navbar navbar-default">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#table-chrome-collapse-variablehistory" aria-expanded="false">
+ <span class="sr-only">Toggle table options</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ </div>
+ <div class="collapse navbar-collapse" id="table-chrome-collapse-variablehistory">
+ <form class="navbar-form navbar-left" id="searchform">
+ <div class="form-group">
+ <div class="btn-group">
+ <input class="form-control" id="search" name="search" type="text" placeholder="Search {%if object_search_display %}{{object_search_display}}{%else%}{{objectname}}{%endif%}" value="{%if request.GET.search %}{{request.GET.search}}{% endif %}"/>
+ {% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" tabindex="-1"><span class="remove-search-btn-variables glyphicon glyphicon-remove-circle"></span></a>{%endif%}
+ </div>
+ </div>
+ <input type="hidden" name="orderby" value="{{request.GET.orderby}}">
+ <input type="hidden" name="page" value="1">
+ <button class="btn btn-default" id="search-button" type="submit" value="Search">Search</button>
+ </form>
+ <form class="navbar-form navbar-right">
+ <div class="form-group">
+ <label>Show rows:</label>
+ <select class="pagesize form-control">
+ {% with "10 25 50 100 150" as list%}
+ {% for i in list.split %}
+ <option value="{{i}}">{{i}}</option>
+ {% endfor %}
+ {% endwith %}
+ </select>
+ </div>
+ </form>
+
+ <div class="btn-group navbar-right">
+ {% if tablecols %}
+ <button id="edit-columns-button" class="btn btn-default navbar-btn dropdown-toggle" data-toggle="dropdown">Edit columns
+ <span class="caret"></span>
+ </button>
<!--
{{tablecols|sortcols}}
-->
- <ul id='editcol' class="dropdown-menu">
- {% for i in tablecols|sortcols %}
- <li>
- <label {% if not i.clclass %} class="checkbox muted" {%else%} class="checkbox" {%endif%}>
- <input type="checkbox" class="chbxtoggle"
- {% if i.clclass %}
+ <ul id="editcol" class="dropdown-menu editcol">
+ {% for i in tablecols|sortcols %}
+ <li>
+ <div class="checkbox">
+ <label {% if not i.clclass %} class="muted" {%endif%}>
+ <input type="checkbox" class="chbxtoggle"
+ {% if i.clclass %}
id="{{i.clclass}}"
value="ct{{i.name}}"
{% if not i.hidden %}
- checked="checked"
+ checked="checked"
{%endif%}
onclick="showhideTableColumn(
- $(this).attr('id'),
- $(this).is(':checked'),
- {% if i.ordericon %}
- '{{i.orderkey}}'
- {% else %}
- undefined
- {% endif %}
+ $(this).attr('id'),
+ $(this).is(':checked'),
+ {% if i.ordericon %}
+ '{{i.orderkey}}'
+ {% else %}
+ undefined
+ {% endif %}
)"
- {%else%}
+ {%else%}
checked disabled
- {% endif %}/> {{i.name}}
- </label>
- </li>
- {% endfor %}
- </ul>
+ {% endif %}/>{{i.name}}
+ </label>
</div>
-{% endif %}
- <div style="display:inline">
- <span class="divider-vertical"></span>
- <span class="help-inline" style="padding-top:5px;">Show rows:</span>
- <select style="margin-top:5px;margin-bottom:0px;" class="pagesize">
- {% with "10 25 50 100 150" as list%}
- {% for i in list.split %}
- <option value="{{i}}">{{i}}</option>
- {% endfor %}
- {% endwith %}
- </select>
- </div>
- </div>
- </div> <!-- navbar-inner -->
-</div>
+ </li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+ </div>
+ </div> <!-- navbar-collapse -->
+ </div> <!-- container-fluid -->
+</div> <!-- navbar-default -->
<!-- the actual rows of the table -->
<table class="table table-bordered table-hover tablesorter" id="otable">
@@ -226,11 +243,11 @@
<!-- Table header row; generated from "tablecols" entry in the context dict -->
<tr>
{% for tc in tablecols %}<th class="{%if tc.dclass%}{{tc.dclass}}{%endif%} {% if tc.clclass %}{{tc.clclass}}{% endif %}">
- {%if tc.qhelp%}<i class="icon-question-sign get-help" title="{{tc.qhelp}}"></i>{%endif%}
- {%if tc.orderfield%}<a {%if tc.ordericon%} class="sorted" {%endif%}href="javascript:reload_params({'page': 1, 'orderby' : '{{tc.orderfield}}' })">{{tc.name}}</a>{%else%}<span class="muted">{{tc.name}}</span>{%endif%}
+ {%if tc.qhelp%}<span class="glyphicon glyphicon-question-sign get-help" title="{{tc.qhelp}}"></span>{%endif%}
+ {%if tc.orderfield%}<a {%if tc.ordericon%} class="sorted" {%endif%}href="javascript:reload_params({'page': 1, 'orderby' : '{{tc.orderfield}}' })">{{tc.name}}</a>{%else%}<span class="text-muted">{{tc.name}}</span>{%endif%}
{%if tc.ordericon%} <i class="icon-caret-{{tc.ordericon}}"></i>{%endif%}
{%if tc.filter%}<div class="btn-group pull-right">
- <a href="#filter_{{tc.filter.class}}" role="button" class="btn btn-mini {%if request.GET.filter%}{{tc.filter.options|filtered_icon:request.GET.filter}} {%endif%}" {%if request.GET.filter and tc.filter.options|filtered_tooltip:request.GET.filter %} title="<p>{{tc.filter.options|filtered_tooltip:request.GET.filter}}</p><p><a class='btn btn-small btn-primary' href=javascript:reload_params({'filter':''})>Show all {% if filter_search_display %}{{filter_search_display}}{% else %}{{objectname}}{% endif %}</a></p>" {%endif%} data-toggle="modal"> <i class="icon-filter filtered"></i> </a>
+ <a href="#filter_{{tc.filter.class}}" role="button" class="btn btn-xs {%if request.GET.filter%}{{tc.filter.options|filtered_icon:request.GET.filter}} {%endif%}" {%if request.GET.filter and tc.filter.options|filtered_tooltip:request.GET.filter %} title="<p>{{tc.filter.options|filtered_tooltip:request.GET.filter}}</p><p><a class='btn btn-sm btn-primary' href=javascript:reload_params({'filter':''})>Show all {% if filter_search_display %}{{filter_search_display}}{% else %}{{objectname}}{% endif %}</a></p>" {%endif%} data-toggle="modal"> <span class="glyphicon glyphicon-filter filtered"></span> </a>
</div>{%endif%}
</th>{% endfor %}
</tr>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/bpackage.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/bpackage.html
deleted file mode 100644
index 81973cbc6..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/bpackage.html
+++ /dev/null
@@ -1,108 +0,0 @@
-{% extends "basebuildpage.html" %}
-
-{% load projecttags %}
-
-{% block title %} Packages built - {{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}} - {{build.project.name}} - Toaster {% endblock %}
-{% block localbreadcrumb %}
-<li>Packages</li>
-{% endblock %}
-
-{% block nav-packages %}
- <li class="active"><a href="{% url 'packages' build.pk %}">Packages</a></li>
-{% endblock %}
-
-{% block buildinfomain %}
-<div class="span10">
-
-{% if not request.GET.filter and not request.GET.search and not objects.paginator.count %}
-
-<!-- Empty - no data in database -->
-<div class="page-header">
- <h1>
- Packages
- </h1>
-</div>
-<div class="alert alert-info lead">
- <strong>No packages were built.</strong> How did this happen? Well, BitBake reuses as much stuff as possible.
- If all of the packages needed were already built and available in your build infrastructure, BitBake
- will not rebuild any of them. This might be slightly confusing, but it does make everything faster.
-</div>
-
-{% else %}
-
-<div class="page-header">
- <h1>
- {% if request.GET.search and objects.paginator.count > 0 %}
- {{objects.paginator.count}} package{{objects.paginator.count|pluralize}} found
- {%elif request.GET.search and objects.paginator.count == 0%}
- No packages found
- {%else%}
- Packages
- {%endif%}
- </h1>
-</div>
-
- {% if objects.paginator.count == 0 %}
- <div class="row-fluid">
- <div class="alert">
- <form class="no-results input-append" id="searchform">
- <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
- <button class="btn" type="submit" value="Search">Search</button>
- <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all packages</button>
- </form>
- </div>
- </div>
-
- {% else %}
- {% include "basetable_top.html" %}
-
- {% for package in objects %}
-
- <tr class="data">
-
- <!-- Package -->
- <td class="package_name"><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.name}}</a></td>
- <!-- Package Version -->
- <td class="package_version">{%if package.version%}<a href="{% url "package_built_detail" build.pk package.pk %}">{{package.version}}-{{package.revision}}</a>{%endif%}</td>
- <!-- Package Size -->
- <td class="size sizecol">{{package.size|filtered_filesizeformat}}</td>
- <!-- License -->
- <td class="license">{{package.license}}</td>
-
- {%if package.recipe%}
- <!-- Recipe -->
- <td class="recipe__name"><a href="{% url "recipe" build.pk package.recipe.pk %}">{{package.recipe.name}}</a></td>
- <!-- Recipe Version -->
- <td class="recipe__version"><a href="{% url "recipe" build.pk package.recipe.pk %}">{{package.recipe.version}}</a></td>
-
- <!-- Layer -->
- <td class="recipe__layer_version__layer__name">{{package.recipe.layer_version.layer.name}}</td>
- <!-- Layer branch -->
- <td class="recipe__layer_version__branch">{{package.recipe.layer_version.branch}}</td>
- <!-- Layer commit -->
- <td class="recipe__layer_version__layer__commit">
- <a class="btn"
- data-content="<ul class='unstyled'>
- <li>{{package.recipe.layer_version.commit}}</li>
- </ul>">
- {{package.recipe.layer_version.commit|truncatechars:13}}
- </a>
- </td>
- <!-- Layer directory -->
- {%else%}
- <td class="recipe__name"></td>
- <td class="recipe__version"></td>
- <td class="recipe__layer_version__layer__name"></td>
- <td class="recipe__layer_version__branch"></td>
- <td class="recipe__layer_version__layer__commit"></td>
- <td class="recipe__layer_version__local_path"></td>
- {%endif%}
-
- </tr>
- {% endfor %}
-
- {% include "basetable_bottom.html" %}
- {% endif %} {# objects.paginator.count #}
-{% endif %} {# Empty #}
-</div>
-{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builddashboard.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builddashboard.html
index a0da71ea4..02a29816a 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builddashboard.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builddashboard.html
@@ -1,8 +1,9 @@
{% extends "basebuildpage.html" %}
{% load humanize %}
{% load projecttags %}
+{% load field_values_filter %}
-{% block title %} {{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}} - {{build.project.name}} - Toaster {% endblock %}
+{% block title %} {{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}} - {{build.project.name}} - Toaster {% endblock %}
{% block parentbreadcrumb %}
{% if build.get_sorted_target_list.count > 0 %}
{{build.get_sorted_target_list.0.target}}
@@ -13,61 +14,57 @@
{% block buildinfomain %}
<!-- page title -->
-<div class="row-fluid span10">
- <div class="page-header">
- <h1>{{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}}</h1>
+<div class="{% if build.started %}col-md-10{% else %}col-md-12{% endif %}">
+ <div class="page-header build-data">
+ <h1>{{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}}</h1>
</div>
-</div>
<!-- build result bar -->
-<div class="row-fluid span10 pull-right">
- <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}">
- <div class="row-fluid lead">
- <span class="pull-left"><strong>
- {%if build.outcome == build.SUCCEEDED%}Completed{%elif build.outcome == build.FAILED%}Failed{%else%}{%endif%}
- </strong> on
- {{build.completed_on|date:"d/m/y H:i"}}
-</span>
-{% if build.warnings.count or build.errors.count %}
-&nbsp;with
-{% endif %}
-{%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
-{% if build.errors.count %}
- <span > <i class="icon-minus-sign red"></i><strong><a href="#errors" class="error show-errors"> {{build.errors.count}} error{{build.errors.count|pluralize}}</a></strong></span>
-{% endif %}
-{% if build.warnings.count %}
-{% if build.errors.count %}
- and
-{% endif %}
- <span > <i class="icon-warning-sign yellow"></i><strong><a href="#warnings" class="warning show-warnings"> {{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a></strong></span>
-{% endif %}
- <span class="pull-right">Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a>
- {% if build.cooker_log_path %}
- <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%else%}btn-danger{%endif%} pull-right log" href="{% url 'build_artifact' build.id "cookerlog" build.id %}">Download build log</a>
- {% endif %}
- </span>
+ <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-danger{%else%}alert-info{%endif%}">
+ <span><strong>{%if build.outcome == build.SUCCEEDED%}Completed{%elif build.outcome == build.FAILED%}Failed{%else%}{%endif%}</strong> on {{build.completed_on|date:"d/m/y H:i"}}</span>
+ {% if build.warnings.count or build.errors.count %}
+ <span>with</span>
+ {% endif %}
+ {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
+ {% if build.errors.count %}
+ <a href="#errors" class="alert-link show-errors"> {{build.errors.count}} error{{build.errors.count|pluralize}}</a>
+ {% endif %}
+ {% if build.warnings.count %}
+ {% if build.errors.count %}and{% endif %}
+ <a href="#warnings" class="show-warnings"> {{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>
+ {% endif %}
+ {% if build.cooker_log_path %}
+ <a class="pull-right log" href="{% url 'build_artifact' build.id "cookerlog" build.id %}">Download build log</a>
+ {% endif %}
+ <span class="pull-right">
+ Build time:
+ <span data-build-field="buildtime">
+ {% if build.outcome == build.SUCCEEDED %}
+ <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a>
+ {% else %}
+ {{ build.timespent_seconds|sectohms }}
+ {% endif %}
+ </span>
+ </span>
-{%endif%}
- </div>
- </div>
+ {%endif%}
</div>
{% if build.errors.count %}
-<div class="accordion span10 pull-right" id="errors">
- <div class="accordion-group">
- <div class="accordion-heading">
- <a class="accordion-toggle error toggle-errors">
- <h2 id="error-toggle">
- <i class="icon-minus-sign"></i>
+ <div class="panel panel-default" id="errors">
+ <div class="panel-heading">
+ <h2 class="panel-title">
+ <span class="glyphicon glyphicon-minus-sign"></span>
+ <a data-toggle="collapse" href="#error-info" id="error-toggle">
{{build.errors.count}} error{{build.errors.count|pluralize}}
- </h2>
- </a>
+ </a>
+ </h2>
</div>
- <div class="accordion-body collapse in" id="collapse-errors">
- <div class="accordion-inner">
- <div class="span10">
+ <div class="panel-collapse collapse in" id="error-info">
+ <div class="panel-body">
+ <div class="{% if build.started %}col-md-10{% else %}col-md-12{% endif %}">
{% for error in build.errors %}
- <div class="alert alert-error" data-error="{{ error.id }}">
+ <div class="alert alert-danger" data-log-message-id="{{error.pk}}">
<pre>{{error.message}}</pre>
</div>
{% endfor %}
@@ -75,57 +72,62 @@
</div>
</div>
</div>
-</div>
{% endif %}
{%if build.outcome == build.SUCCEEDED%}
<!-- built images -->
-{% if hasImages %}
-<div class="row-fluid span10 pull-right">
- <h2>Images</h2>
+ {% if hasArtifacts %}
+ <h2 data-heading="build-artifacts">Build artifacts</h2>
{% for target in targets %}
{% if target.target.is_image %}
- <div class="well dashboard-section">
- <h3><a href="{% url 'target' build.pk target.target.pk %}">{{target.target}}</a>
- </h3>
- <dl class="dl-horizontal">
- <dt>Packages included</dt>
- <dd><a href="{% url 'target' build.pk target.target.pk %}">{{target.npkg}}</a></dd>
- <dt>Total package size</dt>
- <dd>{{target.pkgsz|filtered_filesizeformat}}</dd>
- {% if target.targetHasNoImages %}
- </dl>
- <div class="row-fluid">
- <div class="alert alert-info span7">
- <p>
- <b>This build did not create any image files</b>
- </p>
- <p>
- This is probably because valid image and license manifest
- files from a previous build already exist in your
- <code>.../poky/build/tmp/deploy</code>
- directory. You can
- also <a href="{% url 'targetpkg' build.pk target.target.pk %}">view the
- license manifest information</a> in Toaster.
- </p>
- </div>
- </div>
+ <div class="well well-transparent dashboard-section" data-artifacts-for-target="{{target.target.pk}}">
+ {% if target.npkg > 0 %}
+ <h3>
+ <a href="{% url 'target' build.pk target.target.pk %}" data-link="target-packages">
+ {{target.target.target}}
+ </a>
+ </h3>
+ <dl class="dl-horizontal">
+ <dt>Packages included</dt>
+ <dd>
+ <a href="{% url 'target' build.pk target.target.pk %}">
+ <span data-value="target-package-count">{{target.npkg}}</span>
+ </a>
+ </dd>
+ <dt>Total package size</dt>
+ <dd>
+ <span data-value="target-package-size">{{target.pkgsz|filtered_filesizeformat}}</span>
+ </dd>
+ </dl>
{% else %}
- <dt>
- <i class="icon-question-sign get-help" title="The location in disk of the license manifest, a document listing all packages installed in your image and their licenses"></i>
+ <h3>{{target.target.target}}</h3>
+ {% endif %}
- License manifest
+ {% if target.targetHasImages %}
+ <dl class="dl-horizontal">
+ <dt>
+ Manifests
</dt>
+
<dd>
- <a href="{% url 'targetpkg' build.pk target.target.pk %}">View in Toaster</a> |
- <a href="{% url 'build_artifact' build.pk 'licensemanifest' target.target.pk %}">Download</a></dd>
+ <a data-link="license-manifest" href="{% url 'build_artifact' build.pk 'licensemanifest' target.target.pk %}">License manifest</a>
+ </dd>
+
+ {% if target.target.package_manifest_path %}
+ <dd>
+ <a data-link="package-manifest" href="{% url 'build_artifact' build.pk 'packagemanifest' target.target.pk %}">Package manifest</a>
+ </dd>
+ {% endif %}
+ </dl>
+
+ <dl class="dl-horizontal">
<dt>
- <i class="icon-question-sign get-help" title="Image files are stored in <code>/build/tmp/deploy/images/</code>"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Image files are stored in <code>build/tmp/deploy/images/</code>"></span>
Image files
</dt>
<dd>
- <ul>
- {% for i in target.imageFiles %}
+ <ul class="list-unstyled" data-links="image-artifacts">
+ {% for i in target.imageFiles|dictsort:"suffix" %}
<li>
<a href="{% url 'build_artifact' build.pk 'imagefile' i.id %}">
{{i.suffix}}
@@ -135,13 +137,42 @@
{% endfor %}
</ul>
</dd>
- </dl>
+ <dt>
+ Kernel artifacts
+ </dt>
+ <dd>
+ <ul class="list-unstyled" data-links="kernel-artifacts">
+ {% for artifact in target.target_kernel_artifacts|dictsort:"basename" %}
+ <li>
+ <a href="{% url 'build_artifact' build.id 'targetkernelartifact' artifact.id %}">{{artifact.basename}}</a>
+ ({{artifact.file_size|filtered_filesizeformat}})
+ </li>
+ {% endfor %}
+ </ul>
+ </dd>
+ </dl>
+ {% endif %}
+ {% if target.target_sdk_artifacts_count > 0 %}
+ <dl class="dl-horizontal">
+ <dt>
+ SDK artifacts
+ </dt>
+ <dd>
+ <ul class="list-unstyled" data-links="sdk-artifacts">
+ {% for artifact in target.target_sdk_artifacts|dictsort:"basename" %}
+ <li>
+ <a href="{% url 'build_artifact' build.id 'targetsdkartifact' artifact.id %}">{{artifact.basename}}</a>
+ ({{artifact.file_size|filtered_filesizeformat}})
+ </li>
+ {% endfor %}
+ </ul>
+ </dd>
+ </dl>
{% endif %}
</div>
{% endif %}
{% endfor %}
-</div>
-{% endif %}
+ {% endif %}
{%else%}
<!-- error dump -->
@@ -149,13 +180,12 @@
<!-- other artifacts -->
{% if build.buildartifact_set.all.count > 0 %}
-<div class="row-fluid span10 pull-right">
<h2>Other artifacts</h2>
- <div class="well dashboard-section">
+ <div class="well well-transparent dashboard-section">
<dl class="dl-horizontal">
<dt>
- <i class="icon-question-sign get-help" title="Build artifacts discovered in <i>tmp/deploy/images</i>. Usually kernel images and kernel modules."></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Build artifacts discovered in <i>tmp/deploy/images</i>. Usually kernel images and kernel modules."></span>
Other artifacts</dt>
<dd><div>
{% for ba in build.buildartifact_set.all|dictsort:"file_name" %}
@@ -170,92 +200,97 @@
</dl>
</div>
-</div>
{% endif %}
-<!-- build summary -->
-<div class="row-fluid span10 pull-right">
-<h2>Build summary</h2>
- <div class="well span4 dashboard-section" style="margin-left:0px;">
- <h4><a href="{%url 'configuration' build.pk%}">Configuration</a></h4>
- <dl>
- <dt>Machine</dt><dd>{{build.machine}}</dd>
- <dt>Distro</dt><dd>{{build.distro}}</dd>
- <dt>Layers</dt>{% for i in build.layer_version_build.all|dictsort:"layer.name" %}<dd>{{i.layer.name}}</dd>{%endfor%}
- </dl>
- </div>
- <div class="well span4 dashboard-section">
- <h4><a href="{%url 'tasks' build.pk%}">Tasks</a></h4>
- <dl>
- {% query build.task_build outcome=4 order__gt=0 as exectask%}
- {% if exectask.count > 0 %}
- <dt>Failed tasks</dt>
- <dd>
- {% if exectask.count == 1 %}
- <a class="error" href="{% url "task" build.id exectask.0.id %}">
- {{exectask.0.recipe.name}}
- <span class="task-name">{{exectask.0.task_name}}</span>
- </a>
- <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}">
- <i class="icon-download-alt" title="" data-original-title="Download task log file"></i>
- </a>
+{% if build.started %}
+ <!-- build summary -->
+ <h2 data-role="build-summary-heading">Build summary</h2>
+ <div class="row">
+ <div class="col-md-4 dashboard-section">
+ <div class="well well-transparent">
+ <h3><a href="{%url 'configuration' build.pk%}">Configuration</a></h3>
+ <dl>
+ <dt>Machine</dt><dd>{{build.machine}}</dd>
+ <dt>Distro</dt><dd>{{build.distro}}</dd>
+ <dt>Layers</dt><dd><ul class="list-unstyled">{% for i in build.layer_version_build.all|dictsort:"layer.name" %}<li>{{i.layer.name}}</li>{%endfor%}</ul></dd>
+ </dl>
+ </div>
+ </div>
+ <div class="col-md-4 dashboard-section">
+ <div class="well well-transparent">
+ <h3><a href="{%url 'tasks' build.pk%}">Tasks</a></h3>
+ <dl>
+ {% query build.task_build outcome=4 order__gt=0 as exectask%}
+ {% if exectask.count > 0 %}
+ <dt>Failed tasks</dt>
+ <dd>
+ {% if exectask.count == 1 %}
+ <a class="text-danger" href="{% url "task" build.id exectask.0.id %}">
+ {{exectask.0.recipe.name}}
+ <span class="task-name">{{exectask.0.task_name}}</span>
+ </a>
- {% elif exectask.count > 1%}
- <a class="error" href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}}</a>
- {% endif %}
- </dd>
- {% endif %}
- <dt>Total number of tasks</dt><dd><a href="{% url 'tasks' build.pk %}">{% query build.task_build order__gt=0 as alltasks %}{{alltasks.count}}</a></dd>
- <dt>
- Tasks executed
- <i class="icon-question-sign get-help" title="'Executed' tasks are those that need to be run in order to generate the task output"></i>
- </dt>
- <dd><a href="{% url 'tasks' build.pk %}?filter=task_executed%3A1&amp;count=25&amp;search=&amp;page=1&amp;orderby=order%3A%2B">{% query build.task_build task_executed=1 order__gt=0 as exectask%}{{exectask.count}}</a></dd>
- <dt>
- Tasks not executed
- <i class="icon-question-sign get-help" title="'Not executed' tasks don't need to run because their outcome is provided by another task"></i>
- </dt>
- <dd><a href="{% url 'tasks' build.pk %}?filter=task_executed%3A0&amp;count=25&amp;search=&amp;page=1&amp;orderby=order%3A%2B">{% query build.task_build task_executed=0 order__gt=0 as noexectask%}{{noexectask.count}}</a></dd>
- <dt>
- Reuse
- <i class="icon-question-sign get-help" title="The percentage of 'not executed' tasks over the total number of tasks, which is a measure of the efficiency of your build"></i>
- </dt>
- <dd>
-{% query build.task_build order__gt=0 as texec %}
-{% if noexectask.count|multiply:100|divide:texec.count < 0 %}
-0
-{% else %}
-{{noexectask.count|multiply:100|divide:texec.count}}
-{% endif %}
-%
- </dd>
- </dl>
- </div>
- <div class="well span4 dashboard-section">
- <h4><a href="{% url 'recipes' build.pk %}">Recipes</a> & <a href="{% url 'packages' build.pk %}">Packages</a></h4>
- <dl>
- <dt>Recipes built</dt><dd><a href="{% url 'recipes' build.pk %}">{{recipecount}}</a></dd>
- <dt>Packages built</dt><dd><a href="{% url 'packages' build.pk %}">{{packagecount}}</a></dd>
- </dl>
+ <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}">
+ <span class="glyphicon glyphicon-download-alt get-help" title="Download task log file"></i>
+ </a>
+
+ {% elif exectask.count > 1%}
+ <a class="text-danger" href="{% url "tasks" build.id %}?limit=25&amp;page=1&amp;orderby=order&amp;filter=task_outcome:failed&amp;default_orderby=order&amp;filter_value=on&amp;">{{exectask.count}}</a>
+ {% endif %}
+ </dd>
+ {% endif %}
+ <dt>Total number of tasks</dt><dd><a href="{% url 'tasks' build.pk %}">{% query build.task_build order__gt=0 as alltasks %}{{alltasks.count}}</a></dd>
+ <dt>
+ Tasks executed
+ <span class="glyphicon glyphicon-question-sign get-help" title="'Executed' tasks are those that need to be run in order to generate the task output"></span>
+ </dt>
+ <dd><a href="{% url 'tasks' build.pk %}?limit=25&amp;page=1&amp;orderby=order&amp;filter=execution_outcome:executed&amp;default_orderby=order&amp;filter_value=on&amp;">{% query build.task_build task_executed=1 order__gt=0 as exectask%}{{exectask.count}}</a></dd>
+ <dt>
+ Tasks not executed
+ <span class="glyphicon glyphicon-question-sign get-help" title="'Not executed' tasks don't need to run because their outcome is provided by another task"></span>
+ </dt>
+ <dd><a href="{% url 'tasks' build.pk %}?limit=25&amp;page=1&amp;orderby=order&amp;filter=execution_outcome:not_executed&amp;default_orderby=order&amp;filter_value=on&amp;">{% query build.task_build task_executed=0 order__gt=0 as noexectask%}{{noexectask.count}}</a></dd>
+ <dt>
+ Reuse
+ <span class="glyphicon glyphicon-question-sign get-help" title="The percentage of 'not executed' tasks over the total number of tasks, which is a measure of the efficiency of your build"></span>
+ </dt>
+ <dd>
+ {% query build.task_build order__gt=0 as texec %}
+ {% if noexectask.count|multiply:100|divide:texec.count < 0 %}
+ 0
+ {% else %}
+ {{noexectask.count|multiply:100|divide:texec.count}}
+ {% endif %}
+ %
+ </dd>
+ </dl>
+ </div>
+ </div>
+ <div class="col-md-4 dashboard-section">
+ <div class="well well-transparent">
+ <h3><a href="{% url 'recipes' build.pk %}">Recipes</a> & <a href="{% url 'packages' build.pk %}">Packages</a></h3>
+ <dl>
+ <dt>Recipes built</dt><dd><a href="{% url 'recipes' build.pk %}">{{recipecount}}</a></dd>
+ <dt>Packages built</dt><dd><a href="{% url 'packages' build.pk %}">{{packagecount}}</a></dd>
+ </dl>
+ </div>
</div>
-</div>
+ </div>
+{% endif %} <!-- end build summary -->
{% if build.warnings.count %}
-<div class="accordion span10 pull-right" id="warnings">
- <div class="accordion-group">
- <div class="accordion-heading">
- <a class="accordion-toggle warning toggle-warnings">
- <h2 id="warning-toggle">
- <i class="icon-warning-sign"></i>
- {{build.warnings.count}} warning{{build.warnings.count|pluralize}}
- </h2>
- </a>
+ <div class="panel panel-default" id="warnings">
+ <div class="panel-heading">
+ <h2 class="panel-title">
+ <span class="glyphicon glyphicon-warning-sign"></span>
+ <a id="warning-toggle" href="#warning-info" data-toggle="collapse">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>
+ </h2>
</div>
- <div class="accordion-body collapse" id="collapse-warnings">
- <div class="accordion-inner">
- <div class="span10">
+ <div class="panel-collapse collapse" id="warning-info">
+ <div class="panel-body">
+ <div class="{% if build.started %}col-md-10{% else %}col-md-12{% endif %}">
{% for warning in logmessages %}{% if warning.level == 1 %}
- <div class="alert alert-warning">
+ <div class="alert alert-warning" data-log-message-id="{{warning.pk}}">
<pre>{{warning.message}}</pre>
</div>
{% endif %}{% endfor %}
@@ -263,15 +298,21 @@
</div>
</div>
</div>
-</div>
{% endif %}
+</div> <!-- end 10 column row -->
+
<script type="text/javascript">
$(document).ready(function() {
//show warnings section when requested from the previous page
if (location.href.search('#warnings') > -1) {
- $('#collapse-warnings').addClass('in');
+ $('#warning-info').addClass('in');
}
+
+ //show warnings section when requested from the build outcome
+ $(".show-warnings").click(function() {
+ $('#warning-info').addClass('in');
+ });
});
</script>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildinfo-toastertable.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildinfo-toastertable.html
new file mode 100644
index 000000000..eb4c65690
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildinfo-toastertable.html
@@ -0,0 +1,25 @@
+{% extends "basebuildpage.html" %}
+
+{% load projecttags %}
+
+{% block title %} {{title}} - {{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}} - {{build.project.name}} - Toaster {% endblock %}
+{% block localbreadcrumb %}
+<li>{{title}}</li>
+{% endblock %}
+
+{% block nav-packages %}
+{% endblock %}
+
+{% block buildinfomain %}
+<div class="col-md-10">
+{# xhr_table_url is just the current url so leave it blank #}
+{% with xhr_table_url='' %}
+ <div class="page-header build-data">
+ <h1>
+ {{title}} (<span class="table-count-{{table_name}}">0</span>) </h2>
+ </h1>
+ </div>
+ {% include "toastertable.html" %}
+{% endwith %}
+</div>
+{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html
deleted file mode 100644
index 70fa1fb9a..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildrequestdetails.html
+++ /dev/null
@@ -1,64 +0,0 @@
-{% extends "baseprojectpage.html" %}
-
-{% load static %}
-{% load projecttags %}
-{% load humanize %}
-
-
-{% block projectinfomain %}
- <!-- begin content -->
-
- <div class="row-fluid">
-
- <!-- end left sidebar container -->
- <!-- Begin right container -->
- <div class="span10">
- <div class="page-header">
- <h1>
- <span data-toggle="tooltip" {%if buildrequest.brtarget_set.all.count > 1%}title="Targets: {%for target in buildrequest.brtarget_set.all%}{{target.target}} {%endfor%}"{%endif%}>{{buildrequest.brtarget_set.all.0.target}} {%if buildrequest.brtarget_set.all.count > 1%}(+ {{buildrequest.brtarget_set.all.count|add:"-1"}}){%endif%} {{buildrequest.get_machine}} </span>
-
- </h1>
- </div>
- <div class="alert alert-error">
- <p class="lead">
- <strong>Failed</strong>
- on {{ buildrequest.updated|date:'d/m/y H:i' }}
- with
-
- <i class="icon-minus-sign error" style="margin-left:6px;"></i>
- <strong><a class="error accordion-toggle toggle-errors" href="#errors">
- {{buildrequest.brerror_set.all.count}} error{{buildrequest.brerror_set.all.count|pluralize}}
- </a></strong>
- <span class="pull-right">Build time: {{buildrequest.get_duration|sectohms}}</span>
- </p>
- </div>
-
- <div class="accordion" id="errors">
- <div class="accordion-group">
- <div class="accordion-heading">
- <a class="accordion-toggle error toggle-errors">
- <h2>
- <i class="icon-minus-sign"></i>
- {{buildrequest.brerror_set.all.count}} error{{buildrequest.brerror_set.all.count|pluralize}}
- </h2>
- </a>
- </div>
- <div class="accordion-body collapse in" id="collapse-errors">
- <div class="accordion-inner">
- <div class="span10">
- {% for error in buildrequest.brerror_set.all %}
- <div class="alert alert-error">
- ERROR: <div class="air well"><pre>{{error.errmsg}}</pre></div>
- </div>
- {% endfor %}
- </div>
- </div>
- </div>
-
- </div>
- </div>
- </div>
- </div> <!-- end of row-fluid -->
-
-
-{%endblock%}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builds-toastertable.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builds-toastertable.html
index bf13a66bd..0afe0a311 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builds-toastertable.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/builds-toastertable.html
@@ -13,16 +13,20 @@
{% block pagecontent %}
- <div class="row-fluid">
+<div class="row">
+ <div class="col-md-12">
{% with mru=mru mrb_type=mrb_type %}
{% include 'mrb_section.html' %}
{% endwith %}
- <h1 class="page-header top-air" data-role="page-title"></h1>
+ <div class="page-header">
+ <h1 class="top-air" data-role="page-title"></h1>
+ </div>
{% url 'builds' as xhr_table_url %}
{% include 'toastertable.html' %}
</div>
+</div>
<script>
$(document).ready(function () {
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildtime.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildtime.html
deleted file mode 100644
index ea84ae797..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/buildtime.html
+++ /dev/null
@@ -1,4 +0,0 @@
-{% extends "basebuildpage.html" %}
-{% block localbreadcrumb %}
-<li>Build Time</li>
-{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configuration.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configuration.html
index 85d6a622a..58989f865 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configuration.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configuration.html
@@ -6,21 +6,17 @@
<li>Configuration</li>
{% endblock %}
-{% block nav-configuration %}
- <li class="active"><a href="{% url 'configuration' build.pk %}">Configuration</a></li>
-{% endblock %}
-
{% block buildinfomain %}
<!-- page title -->
-<div class="row-fluid span10">
- <div class="page-header">
+<div class="col-md-10">
+
+ <div class="page-header build-data">
<h1>Configuration</h1>
</div>
-</div>
<!-- configuration table -->
-<div class="row-fluid pull-right span10" id="navTab">
-<ul class="nav nav-pills">
+<div id="navTab">
+<ul class="nav nav-tabs">
<li class="active"><a href="#">Summary</a></li>
<li class=""><a href="{% url 'configvars' build.id %}">BitBake variables</a></li>
</ul>
@@ -39,34 +35,51 @@
{%if TUNE_FEATURES %}<dt>Tune features</dt><dd>{{TUNE_FEATURES}}</dd> {% endif %}
{%if TARGET_FPU %}<dt>Target FPU</dt><dd>{{TARGET_FPU}}</dd> {% endif %}
{%if targets.all %}<dt>Target(s)</dt>
- <dd> <ul> {% for target in targets.all %}
+ <dd> <ul class="list-unstyled"> {% for target in targets.all %}
<li>{{target.target}}{%if forloop.counter > 1 %}<br>{% endif %}</li>
{% endfor %} </ul> </dd> {% endif %}
</dl>
<h3>Layers</h3>
- <div class="span9" style="margin-left:0px;">
- <table class="table table-bordered table-hover">
- <thead>
- <tr>
- <th>Layer</th>
- <th>Layer branch</th>
- <th>Layer commit</th>
- </tr>
- </thead>
- <tbody>{% for lv in build.layer_version_build.all|dictsort:"layer.name" %}
- <tr>
+ <div class="row">
+ <div class="col-md-9 table-responsive">
+ <table class="table table-bordered table-hover">
+ <thead>
+ <tr>
+ <th>Layer</th>
+ <th>Layer branch</th>
+ <th>Layer commit</th>
+ </tr>
+ </thead>
+ <tbody>{% for lv in build.layer_version_build.all|dictsort:"layer.name" %}
+ <tr>
<td>{{lv.layer.name}}</td>
+ {% if lv.layer.local_source_dir %}
+ <td>
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{lv.layer.name}} is not in a Git repository, so there is no branch associated with it"> </span>
+ </td>
+ {% else %}
<td>{{lv.branch}}</td>
- <td> <a class="btn" data-content="<ul class='unstyled'>
- <li>{{lv.commit}}</li> </ul>">
- {{lv.commit|truncatechars:13}}
- </a></td>
- </tr>{% endfor %}
- </tbody>
- </table>
+ {% endif %}
+ {% if lv.layer.local_source_dir %}
+ <td>
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{lv.layer.name}} is not in a Git repository, so there is no commit associated with it"> </span>
+ </td>
+ {% else %}
+ <td> <a class="btn btn-default" data-content="<ul class='list-unstyled'>
+ <li>{{lv.commit}}</li> </ul>">
+ {{lv.commit|truncatechars:13}}
+ </a></td>
+ {% endif %}
+ </tr>{% endfor %}
+ </tbody>
+ </table>
+ </div>
</div>
</div>
-
</div>
+
+</div> <!-- end of 10-column section -->
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configvars.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configvars.html
index e40c225a3..ca2e1eab3 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configvars.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/configvars.html
@@ -6,14 +6,10 @@
<li>Configuration</li>
{% endblock %}
-{% block nav-configuration %}
- <li class="active"><a href="{% url 'configuration' build.pk %}">Configuration</a></li>
-{% endblock %}
-
{% block buildinfomain %}
<!-- page title -->
-<div class="row-fluid span10">
- <div class="page-header">
+<div class="col-md-10">
+ <div class="page-header build-data">
<h1>
{% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %}
{{objects.paginator.count}} variable{{objects.paginator.count|pluralize}} found
@@ -24,11 +20,10 @@
{%endif%}
</h1>
</div>
-</div>
<!-- configuration table -->
-<div class="row-fluid pull-right span10" id="navTab">
- <ul class="nav nav-pills">
+<div id="navTab">
+ <ul class="nav nav-tabs">
<li class=""><a href="{% url 'configuration' build.id %}">Summary</a></li>
<li class="active"><a href="#" >BitBake variables</a></li>
</ul>
@@ -37,14 +32,21 @@
<div id="variables" class="tab-pane">
{% if objects.paginator.count == 0 %}
- <div class="row-fluid">
- <div class="alert">
- <form class="no-results input-append" id="searchform">
- <input id="search" name="search" class="input-xxlarge" type="text" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
- <button class="btn" type="submit" value="Search">Search</button>
- <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all variables</button>
- </form>
+ <div class="alert alert-warning">
+ <form class="no-results form-inline" id="searchform">
+ <div class="form-group">
+ <div class="btn-group">
+ <input class="form-control" id="search" name="search" type="text" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>
+ {% if request.GET.search %}
+ <a href="javascript:$('#search').val('');searchform.submit()" tabindex="-1">
+ <span class="remove-search-btn-variables glyphicon glyphicon-remove-circle"></span>
+ </a>
+ {% endif %}
+ </div>
</div>
+ <button class="btn btn-default" type="submit" value="Search">Search</button>
+ <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all variables</button>
+ </form>
</div>
{% else %}
@@ -53,81 +55,91 @@
{% for variable in objects %}
<tr class="data">
<td class="variable_name"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_name}}</a></td>
- <td class="variable_value"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_value|truncatechars:153}}</a></td>
- <td class="file"><a data-toggle="modal" href="#variable-{{variable.pk}}">
+ <td class="variable_value">{{variable.variable_value|truncatechars:153}}</td>
+ <td class="file">
{% if variable.vhistory.all %}
{% for path in variable.vhistory.all|filter_setin_files:file_filter %}
{{path}}<br/>
{% endfor %}
{% endif %}
- </a></td>
+ </td>
<td class="description">
{% if variable.description %}
{{variable.description}}
<a href="http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-{{variable.variable_name|variable_parent_name}}" target="_blank">
- <i class="icon-share get-info"></i></a>
+ <span class="glyphicon glyphicon-new-window get-info"></span></a>
{% endif %}
</td>
</tr>
{% endfor %}
-
+</tbody>
+</table>
+</div> <!-- table-responsive -->
{% include "basetable_bottom.html" %}
{% endif %}
</div> <!-- endvariables -->
<!-- file list popups -->
{% for variable in objects %}
- {% if variable.vhistory.count %}
- <div id="variable-{{variable.pk}}" class="modal hide fade" tabindex="-1" role="dialog">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
- <h3>History of {{variable.variable_name}}</h3>
- </div>
- <div class="modal-body">
- {% if variable.variable_value %}
- {% if variable.variable_value|length < 570 %}
- <h4>{{variable.variable_name}} value is:</h4>
- <p>
- {{variable.variable_value}}
- </p>
- {% else %}
- <h4>{{variable.variable_name}} value is:</h4>
- <p>
- <span>{{variable.variable_value|string_slice:':570'}}
- <span class="full"> {{variable.variable_value|string_slice:'570:'}}
- </span>
- <a class="btn btn-mini full-show">...</a>
- </span>
- </p>
- <a class="btn btn-mini full-hide">Collapse variable value <i class="icon-caret-up"></i>
- </a>
- {% endif %}
- {% else %}
- <div class="alert alert-info">The value of <strong>{{variable.variable_name}}</strong> is an empty string</div>
- {% endif %}
- <h4>The value was set in the following configuration files:</h4>
- <table class="table table-bordered table-hover">
- <thead>
- <tr>
- <th>Order</th>
- <th>Configuration file</th>
- <th>Operation</th>
- <th>Line number</th>
- </tr>
- </thead>
- <tbody>
- {% for vh in variable.vhistory.all %}
- <tr>
- <td>{{forloop.counter}}</td><td>{{vh.file_name}}</td><td>{{vh.operation}}</td><td>{{vh.line_number}}</td>
- </tr>
- {%endfor%}
- </tbody>
- </table>
+{% if variable.vhistory.count %}
+<div id="variable-{{variable.pk}}" class="modal fade" tabindex="-1" role="dialog">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
+ <h3>History of {{variable.variable_name}}</h3>
+ </div>
+ <div class="modal-body">
+ {% if variable.variable_value %}
+ {% if variable.variable_value|length < 570 %}
+ <h4>{{variable.variable_name}} value is:</h4>
+ <p>
+ {{variable.variable_value}}
+ </p>
+ {% else %}
+ <h4>{{variable.variable_name}} value is:</h4>
+ <p>
+ <span>{{variable.variable_value|string_slice:':570'}}
+ <span class="full"> {{variable.variable_value|string_slice:'570:'}}
+ </span>
+ <a href="#" class="full-show">...</a>
+ </span>
+ </p>
+ <a href="#" class="full-hide">Collapse variable value <i class="icon-caret-up"></i>
+ </a>
+ {% endif %}
+ {% else %}
+ <div class="alert alert-info">The value of <strong>{{variable.variable_name}}</strong> is an empty string</div>
+ {% endif %}
+ <h4>The value was set in the following configuration files:</h4>
+ <div class="table-responsive">
+ <table class="table table-bordered table-hover">
+ <thead>
+ <tr>
+ <th>Order</th>
+ <th>Configuration file</th>
+ <th>Operation</th>
+ <th>Line</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for vh in variable.vhistory.all %}
+ <tr>
+ <td>{{forloop.counter}}</td><td class="file">{{vh.file_name}}</td><td>{{vh.operation}}</td><td>{{vh.line_number}}</td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
</div>
- </div>
- {% endif %}
+ </div>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->
+{% endif %}
{% endfor %}
</div> <!-- buildinfomain -->
+</div> <!-- end 10-column section -->
+
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customise_btn.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customise_btn.html
index 2e54a9d90..38c258ac3 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customise_btn.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customise_btn.html
@@ -1,15 +1,15 @@
-<button class="btn btn-block layer-exists-{{data.layer_version.pk}} customise-btn" data-recipe="{{data.pk}}"
+<button class="btn btn-default btn-block layer-exists-{{data.layer_version.pk}} customise-btn" data-recipe="{{data.pk}}"
{% if data.layer_version.pk not in extra.current_layers %}
style="display:none;"
{% endif %}
>
Customise
</button>
-<button class="btn btn-block layer-add-{{data.layer_version.pk}} layerbtn" data-layer='{ "id": {{data.layer_version.pk}}, "name": "{{data.layer_version.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.pk%}"}' data-directive="add"
+<button class="btn btn-default btn-block layer-add-{{data.layer_version.pk}} layerbtn" data-layer='{ "id": {{data.layer_version.pk}}, "name": "{{data.layer_version.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.pk%}"}' data-directive="add"
{% if data.layer_version.pk in extra.current_layers %}
style="display:none;"
{% endif %}
>
- <i class="icon-plus"></i>
+ <i class="glyphicon glyphicon-plus"></i>
Add layer
</button>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customrecipe.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customrecipe.html
index ea3c9c732..945fc9797 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customrecipe.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/customrecipe.html
@@ -4,7 +4,7 @@
{% load static %}
{% block pagecontent %}
-<div class="section">
+{% with recipe.get_base_recipe_file as base_recipe_file %}
<ul class="breadcrumb">
<li>
<a href="{% url 'project' project.id %}">{{project.name}}</a>
@@ -17,7 +17,6 @@
{{recipe.name}} ({{recipe.layer_version.layer.name}})
</li>
</ul>
-</div>
<script src="{% static 'js/customrecipe.js' %}"></script>
<script>
@@ -29,6 +28,7 @@
includedPackagesCount: {{recipe.includes_set.count}},
baseRecipeId: {{recipe.base_recipe.pk}},
xhrPackageListUrl: "{% url 'xhr_customrecipe_packages' recipe.pk %}",
+ xhrCustomRecipeUrl: "{% url 'xhr_customrecipe_id' recipe.pk %}",
}
};
@@ -40,95 +40,137 @@
}
});
</script>
+
+<!-- Delete recipe modal -->
+<div id="delete-recipe-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-body">
+ <p>Are you sure you want to delete the <strong>{{recipe.name}}</strong>
+ custom image?</p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-primary" id="delete-custom-recipe-confirmed">
+ <span data-role="submit-state">Delete custom image</span>
+ <span data-role="loading-state" style="display:none">
+ <span class="fa-pulse">
+ <i class="fa-pulse icon-spinner"></i>
+ </span>
+ &nbsp;Deleting custom image...
+ </span>
+ </button>
+ <button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button>
+ </div>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->
+<!-- end delete recipe modal -->
+
<!-- package dependencies modal -->
-<div style="display:none" id="package-deps-modal" class="modal hide fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
- <h3><span class="package-to-add-name"></span> dependencies</h3>
- </div>
- <div class="modal-body">
- <p>Based on information from a previous build it is likely that adding <strong class="package-to-add-name"></strong> will also add the following packages to your custom image:</p>
- <ul id="package-add-dep-list">
- </ul>
- </div>
- <div class="modal-footer">
- <p class="help-block text-left">Total package size: <strong id="package-deps-total-size"></strong></p>
- <button id="add-package-deps-modal-btn" type="submit" class="btn btn-primary" data-dismiss="modal">Add package</button>
- <button class="btn" data-dismiss="modal">Cancel</button>
- </div>
-</div>
+<div id="package-deps-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
+ <h3><span class="package-to-add-name"></span> dependencies</h3>
+ </div>
+ <div class="modal-body">
+ <p>Based on information from a previous build it is likely that adding <strong class="package-to-add-name"></strong> will also add the following packages to your custom image:
+ </p>
+ <ul id="package-add-dep-list">
+ </ul>
+ </div>
+ <div class="modal-footer">
+ <p class="help-block text-left">Total package size: <strong id="package-deps-total-size"></strong></p>
+ <button id="add-package-deps-modal-btn" type="submit" class="btn btn-primary" data-dismiss="modal">Add packages</button>
+ <button class="btn btn-link" data-dismiss="modal">Cancel</button>
+ </div>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->
<!-- end package dependencies modal -->
<!-- package reverse dependencies modal -->
-<div style="display:none" id="package-reverse-deps-modal" class="modal hide fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
- <h3><span class="package-to-rm-name"></span> reverse dependencies</h3>
- </div>
- <div class="modal-body">
- <p> <strong class="reverse-deps-count"></strong> <span class="reverse-deps-package"></span> in your image <span class="reverse-deps-depends"></span> on <strong class="package-to-rm-name"></strong>:</p>
- <ul id="package-reverse-dep-list">
- </ul>
- <p>In order to remove <strong class="package-to-rm-name"></strong>, you must remove <span class="reverse-deps-this"></span> <strong class="reverse-deps-count"></strong> <span class="reverse-deps-package"></span> as well.</p>
- </div>
- <div class="modal-footer">
- <p class="help-block text-left">Total package size: <strong id="package-reverse-deps-total-size"></strong></p>
- <button id="rm-package-reverse-deps-modal-btn" type="submit" class="btn btn-primary" data-dismiss="modal">Remove all <span class="reverse-deps-count-plus1"></button>
- <button class="btn" data-dismiss="modal">Cancel</button>
- </div>
-</div>
+<div style="display:none" id="package-reverse-deps-modal" class="modal fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
+ <h3><span class="package-to-rm-name"></span> reverse dependencies</h3>
+ </div>
+ <div class="modal-body">
+ <p> <strong class="reverse-deps-count"></strong> <span class="reverse-deps-package"></span> in your image <span class="reverse-deps-depends"></span> on <strong class="package-to-rm-name"></strong>:</p>
+ <ul id="package-reverse-dep-list">
+ </ul>
+ <p>In order to remove <strong class="package-to-rm-name"></strong>, you must remove <span class="reverse-deps-this"></span> <strong class="reverse-deps-count"></strong> <span class="reverse-deps-package"></span> as well.</p>
+ </div>
+ <div class="modal-footer">
+ <p class="help-block text-left">Total package size: <strong id="package-reverse-deps-total-size"></strong></p>
+ <button id="rm-package-reverse-deps-modal-btn" type="submit" class="btn btn-primary" data-dismiss="modal">Remove all <span class="reverse-deps-count-plus1"></button>
+ <button class="btn btn-link" data-dismiss="modal">Cancel</button>
+ </div>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->
<!-- end package dependencies modal -->
-
-<div class="row-fluid span11">
- <div class="alert alert-success lead" id="image-created-notification" style="margin-top: 15px; display: none">
- <button type="button" data-dismiss="alert" class="close">x</button>
- Your custom image <strong>{{recipe.name}}</strong> has been created. You can now add or remove packages as needed.
- </div>
- <div class="page-header air">
- <h1>
- {{recipe.name}}
- <small>({{recipe.layer_version.layer.name}})</small>
- </h1>
- </div>
+<div class="alert alert-success alert-dismissible change-notification" id="image-created-notification" style="display: none">
+ <button type="button" data-dismiss="alert" class="close">&times;</button>
+ <p>Your custom image <strong>{{recipe.name}}</strong> has been created. You can now add or remove packages as needed.</p>
+</div>
+<div class="page-header">
+ <h1>
+ {{recipe.name}}
+ <small>({{recipe.layer_version.layer.name}})</small>
+ </h1>
</div>
-<div class="row-fluid span11">
- <div class="span8">
+<div class="row">
+ <div class="col-md-8">
<div class="button-place btn-group" style="width: 100%">
- <a class="btn btn-large span6 build-custom-image" href="#" style="width: 50%">
+ <a class="btn btn-default btn-lg build-custom-image" href="#" style="width: 50%">
Build {{recipe.name}}
</a>
- <a href="{% url 'customrecipedownload' project.id recipe.id %}" class="btn btn-large span6" style="width: 50%">
+ <a href="{% url 'customrecipedownload' project.id recipe.id %}" class="btn btn-default btn-lg" style="width: 50%"
+ {% if not base_recipe_file %}
+ disabled="disabled"
+ {% endif %}>
Download recipe file
+ {% if not base_recipe_file %}
+ <i class="icon-question-sign get-help"
+ data-original-title="The recipe file doesn't exist yet, so you cannot download it. You need to build your custom image first"></i>
+ {% endif %}
</a>
</div>
- <div id="no-results-special-{{table_name}}" class="air" style="display:none;">
- <div class="alert">
+ <div id="no-results-special-{{table_name}}" class="top-air" style="display:none;">
+ <div class="alert alert-warning">
<h3>No packages found</h3>
- <p>You might consider <a href={% url 'projectsoftwarerecipes' project.id %}>searching the list of recipes</a> instead. If you find a recipe that matches the name of the package you want:</p>
+ <p>You might consider <a href={% url 'projectsoftwarerecipes' project.id %}>searching the list of recipes</a> instead.</p>
+ <p>If you find a recipe that matches the name of the package you want:</p>
<ol>
<li>Add the layer providing the recipe to your project</li>
<li>Build the recipe</li>
<li>Once the build completes, come back to this page and search for the package</li>
</ol>
- <form class="input-append no-results">
- <input type="text" class="input-xlarge no-results-search-input" id="no-results-search-input-{{table_name}}" name="search" placeholder="Search {{title|lower}}" />
- <a href="#" class="add-on btn" id="no-results-remove-search-btn" tabindex="-1">
- <i class="icon-remove"></i>
- </a>
- <button class="btn search-submit-{{table_name}}">Search</button>
+ <form class="form-inline no-results">
+ <div class="form-group">
+ <div class="btn-group">
+ <input type="text" class="form-control no-results-search-input" id="no-results-search-input-{{table_name}}" name="search" placeholder="Search {{title|lower}}" />
+ <span class="remove-search-btn-{{table_name}} glyphicon glyphicon-remove-circle" id="no-results-remove-search-btn" tabindex="-1"></span>
+ </div>
+ </div>
+ <button class="btn btn-default search-submit-{{table_name}}">Search</button>
<button class="btn btn-link" id="no-results-show-all-packages">Show all packages</button>
</form>
</div>
- </div>
- <div id="results-found-{{table_name}}">
+ </div>
+ <div id="results-found-{{table_name}}">
<div id="packages-table">
{% if recipe.get_all_packages.count == 0 and last_build == None %}
<h2> Add | Remove packages </h2>
- <div class="alert alert-info air">
+ <div class="alert alert-info">
<p class="lead">Toaster has no package information for {{recipe.name}}. To generate package information, build {{recipe.name}}</p>
- <button class="btn btn-info btn-large build-custom-image" style="margin:20px 0 10px 0;">Build {{recipe.name}}</button>
+ <button class="btn btn-info btn-lg build-custom-image" style="margin:20px 0 10px 0;">Build {{recipe.name}}</button>
</div>
{% else %}
{# ToasterTable for Adding remove packages #}
@@ -137,87 +179,90 @@
{% include "toastertable.html" %}
{% endif %}
</div>
- </div>
</div>
- <div class="span4 well">
- <h2 style="margin-bottom:20px;">About {{recipe.name}}</h2>
+ </div>
+ <div class="col-md-4">
+ <div class="well">
+ <h2>About {{recipe.name}}</h2>
- <dl>
+ <dl class="item-info">
<dt>
- Approx. packages included
- <i class="icon-question-sign get-help" title="" data-original-title="The number of packages included is based on information from previous builds and from parsing layers, so we can never be sure it is 100% accurate"></i>
+ Approx. packages included
+ <span class="glyphicon glyphicon-question-sign get-help" title="" data-original-title="The number of packages included is based on information from previous builds and from parsing layers, so we can never be sure it is 100% accurate"></span>
</dt>
<dd id="total-num-packages">{{recipe.get_all_packages.count}}</dd>
<dt>
- Approx. package size
- <i class="icon-question-sign get-help" title="" data-original-title="Package size is based on information from previous builds, so we can never be sure it is 100% accurate"></i>
+ Approx. package size
+ <span class="glyphicon glyphicon-question-sign get-help" title="Package size is based on information from previous builds, so we can never be sure it is 100% accurate"></span>
</dt>
<dd id="total-size-packages">{{approx_pkg_size.size__sum|filtered_filesizeformat}}</dd>
{% if last_build %}
<dt>Last build</dt>
<dd>
- <i class="icon-ok-sign success"></i>
- <a href="{% url 'projectbuilds' project.id%}">{{last_build.completed_on|date:"d/m/y H:i"}}</a>
+ <span class="glyphicon glyphicon-ok-circle"></span>
+ <a href="{% url 'projectbuilds' project.id%}">{{last_build.completed_on|date:"d/m/y H:i"}}</a>
</dd>
{% endif %}
- <dt>Layer</dt>
- <dd><a href="{% url 'layerdetails' project.id recipe.layer_version.pk %}">{{recipe.layer_version.layer.name}}</a></dd>
<dt>Based on</dt>
<dd><a href="{% url 'recipedetails' project.id recipe.base_recipe.pk %}">{{recipe.base_recipe.name}}</a></dd>
{% if recipe.get_last_successful_built_target %}
{% with recipe.get_last_successful_built_target as last_build_target %}
<dt>Last build</dt>
<dd>
- <i class="icon-ok-sign success"></i>
- <a href="{% url 'builddashboard' last_build_target.build.pk %}">
- {{last_build_target.build.completed_on|date:"d/m/y H:i"}}</a>
+ <span class="glyphicon glyphicon-ok-circle"></span>
+ <a href="{% url 'builddashboard' last_build_target.build.pk %}">
+ {{last_build_target.build.completed_on|date:"d/m/y H:i"}}</a>
</dd>
{% endwith %}
{% endif %}
+ {% if base_recipe_file %}
<dt>Recipe file</dt>
<dd>
- <code>{{recipe.name}}_{{recipe.version}}.bb</code>
- <a href="{% url 'customrecipedownload' project.pk recipe.pk %}"><i class="icon-share" title="" data-original-title="View recipe file"></i></a>
+ <code>{{recipe.name}}_{{recipe.version}}.bb</code>
+ <a href="{% url 'customrecipedownload' project.pk recipe.pk %}"><span class="glyphicon glyphicon-download-alt" data-toggle="tooltip" title="Download recipe file"></span></a>
</dd>
+ {% endif %}
<dt>Layer</dt>
<dd><a href="{% url 'layerdetails' project.id recipe.layer_version.pk %}">{{recipe.layer_version.layer.name}}</a></dd>
{% if recipe.summary %}
<dt>
- Summary
+ Summary
</dt>
<dd>
- {{recipe.summary}}
+ {{recipe.summary}}
</dd>
{% endif %}
{% if recipe.description %}
<dt>
- Description
+ Description
</dt>
<dd>
- {{recipe.description}}
+ {{recipe.description}}
</dd>
{% endif %}
<dt>Version</dt>
<dd>
- {{recipe.version}}
+ {{recipe.version}}
</dd>
{% if recipe.section %}
<dt>Section</dt>
<dd>
- {{recipe.section}}
+ {{recipe.section}}
</dd>
{% endif %}
<dt>License</dt>
<dd>
- {{recipe.license}}
- <i class="icon-question-sign get-help" title="" data-original-title="All custom images have their license set to MIT. This is because the license applies only to the recipe (.bb) file, and not to the image itself. To see which licenses apply to the image you must check the license manifest generated with each build"></i>
- </dd>
+ {{recipe.license}}
+ <span class="glyphicon glyphicon-question-sign get-help" title="All custom images have their license set to MIT. This is because the license applies only to the recipe (.bb) file, and not to the image itself. To see which licenses apply to the image you must check the license manifest generated with each build"></i>
+ </dd>
</dl>
- <!--
- <i class="icon-trash no-tooltip"></i>
- <a href="#" class="error" id="delete">Delete custom image</a>
- -->
+ <i class="icon-trash text-danger"></i>
+ <a href="#delete-recipe-modal" data-target="#delete-recipe-modal" data-toggle="modal" class="text-danger" id="delete-recipe">
+ Delete custom image
+ </a>
</div>
</div>
+</div>
- {% endblock %}
+{% endwith %}{# end base_recipe_file #}
+{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_pagination_bottom.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_pagination_bottom.html
index f40c21d99..15adfbc91 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_pagination_bottom.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_pagination_bottom.html
@@ -6,8 +6,8 @@
{# only paginate if 10 or more rows unfiltered, all pages #}
{% if object_count >= 10 %}
-<div class="pagination">
- <ul>
+<div id="pagination-detail">
+ <ul class="pagination">
{%if objects.has_previous %}
<li><a href="javascript:reload_params({'page':{{objects.previous_page_number}}})">&laquo;</a></li>
{%else%}
@@ -23,16 +23,18 @@
{%endif%}
</ul>
- <div class="pull-right">
- <span class="help-inline" style="padding-bottom:10px;">Show rows:</span>
- <select class="pagesize">
- {% with "10 25 50 100 150" as list%}
+ <form class="navbar-form navbar-right">
+ <div class=form-group">
+ <label>Show rows:</label>
+ <select class="pagesize form-control">
+ {% with "10 25 50 100 150" as list%}
{% for i in list.split %}
- <option value="{{i}}">{{i}}</option>
+ <option value="{{i}}">{{i}}</option>
{% endfor %}
- {% endwith %}
- </select>
- </div>
+ {% endwith %}
+ </select>
+ </div>
+ </form>
</div>
<!-- Update page display settings -->
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_search_header.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_search_header.html
index 7bea3f47f..7a9865908 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_search_header.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_search_header.html
@@ -18,51 +18,55 @@ $(document).ready(function() {
});
});
</script>
-<div class="row-fluid">
+
{% if objects.paginator.count > 10 or request.GET.search %}
{% if objects.paginator.count == 0 %}
- <div class="alert">
- <h3>No {{search_what}} found</h3>
- <form id="searchform" class="input-append">
- {% else %}
- <form id="searchform" class="navbar-search input-append pull-left">
- {% endif %}
+ <div class="alert alert-warning">
+ <h4>No {{search_what}} found</h4>
+ <form id="searchform" class="form-inline">
+ {% else %}
+ <form id="searchform" class="navbar-form navbar-left detail-page-controls">
+ {% endif %}
- <input id="search" class="input-xlarge" type="text" placeholder="Search {{search_what}}" name="search" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}">
- <input type="hidden" value="name:+" name="orderby">
- <input type="hidden" value="l" name="page">
- {% if request.GET.search %}
- <a class="add-on btn search-clear">
- <i class="icon-remove"></i>
- </a>
- {% endif %}
- <button type="submit" class="btn">Search</button>
- {% if objects.paginator.count == 0 %}
- <button type="submit" class="btn btn-link search-clear">
- Show all {{search_what}}
- </button>
- {% endif %}
- </form>
-{% endif %}
+ <div class="form-group">
+ <div class="btn-group">
+ <input id="search" class="form-control" type="text" placeholder="Search {{search_what}}" name="search" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}">
+ <input type="hidden" value="name:+" name="orderby">
+ <input type="hidden" value="l" name="page">
+ {% if request.GET.search %}
+ <span class="remove-search-btn-detail-search search-clear glyphicon glyphicon-remove-circle"></span>
+ {% endif %}
+ </div>
+ </div>
+ <button type="submit" class="btn btn-default">Search</button>
+ {% if objects.paginator.count == 0 %}
+ <button type="submit" class="btn btn-link search-clear">
+ Show all {{search_what}}
+ </button>
+ {% endif %}
+ </form>
+ {% endif %}
-{% if objects.paginator.count == 0 %}
+ {% if objects.paginator.count == 0 %}
</div> {# end alert #}
-{% else %}
+ {% else %}
{% if object_count > 10 %}
- <div class="pull-right">
- <span class="help-inline" style="padding-top:5px;">Show rows:</span>
- <select style="margin-top:5px;margin-bottom:0px;" class="pagesize">
- {% with "10 25 50 100 150" as list%}
- {% for i in list.split %}
+ <form class="navbar-form navbar-right">
+ <div class="form-group">
+ <label>Show rows:</label>
+ <select class="pagesize form-control">
+ {% with "10 25 50 100 150" as list%}
+ {% for i in list.split %}
{% if request.session.limit == i %}
- <option value="{{i}}" selected>{{i}}</option>
+ <option value="{{i}}" selected>{{i}}</option>
{% else %}
- <option value="{{i}}">{{i}}</option>
+ <option value="{{i}}">{{i}}</option>
{% endif %}
- {% endfor %}
- {% endwith %}
- </select>
- </div>
+ {% endfor %}
+ {% endwith %}
+ </select>
+ </div>
+ </form>
{% endif %}
{% endif %}
-</div> {# row-fluid #}
+
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_sorted_header.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_sorted_header.html
index 6ce292e5a..4434df439 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_sorted_header.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/detail_sorted_header.html
@@ -10,14 +10,14 @@
<!-- Table header row; generated from "tablecols" entry in the context dict -->
<tr>
{% for tc in tablecols %}<th class="{%if tc.dclass%}{{tc.dclass}}{% endif %} {%if tc.class %}{{tc.clclass}}{% endif %}">
- {%if tc.qhelp%}<i class="icon-question-sign get-help" title="{{tc.qhelp}}"></i>{%endif%}
- {%if tc.orderfield%}<a {%if tc.ordericon%} class="sorted" {%endif%}href="javascript:reload_params({'page': 1, 'orderby' : '{{tc.orderfield}}' })">{{tc.name}}</a>{%else%}<span class="muted">{{tc.name}}</span>{%endif%}
- {%if tc.ordericon%} <i class="icon-caret-{{tc.ordericon}}"></i>{%endif%}
+ {%if tc.qhelp%}<span class="glyphicon glyphicon-question-sign get-help" title="{{tc.qhelp}}"></span>{%endif%}
+ {%if tc.orderfield%}<a {%if tc.ordericon%} class="sorted" {%endif%}href="javascript:reload_params({'page': 1, 'orderby' : '{{tc.orderfield}}' })">{{tc.name}}</a>{%else%}<span class="text-muted">{{tc.name}}</span>{%endif%}
+ {%if tc.ordericon%} <span class="icon-caret-{{tc.ordericon}}"></span>{%endif%}
{% if request.GET.search and forloop.first %}
<span class="badge badge-info">{{objects.paginator.count}}</span>
{% endif %}
{%if tc.filter%}<div class="btn-group pull-right">
- <a href="#filter_{{tc.filter.class}}" role="button" class="btn btn-mini {%if request.GET.filter%}{{tc.filter.options|filtered_icon:request.GET.filter}} {%endif%}" {%if request.GET.filter and tc.filter.options|filtered_tooltip:request.GET.filter %} title="<p>{{tc.filter.options|filtered_tooltip:request.GET.filter}}</p><p><a class='btn btn-small btn-primary' href=javascript:reload_params({'filter':''})>Show all {% if filter_search_display %}{{filter_search_display}}{% else %}{{objectname}}{% endif %}</a></p>" {%endif%} data-toggle="modal"> <i class="icon-filter filtered"></i> </a>
+ <a href="#filter_{{tc.filter.class}}" role="button" class="btn btn-mini {%if request.GET.filter%}{{tc.filter.options|filtered_icon:request.GET.filter}} {%endif%}" {%if request.GET.filter and tc.filter.options|filtered_tooltip:request.GET.filter %} title="<p>{{tc.filter.options|filtered_tooltip:request.GET.filter}}</p><p><a class='btn btn-sm btn-primary' href=javascript:reload_params({'filter':''})>Show all {% if filter_search_display %}{{filter_search_display}}{% else %}{{objectname}}{% endif %}</a></p>" {%endif%} data-toggle="modal"> <i class="glyphicon glyphicon-filter filtered"></i> </a>
</div>{%endif%}
</th>{% endfor %}
</tr>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/dirinfo.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/dirinfo.html
index ecb46bf7a..ab89e279f 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/dirinfo.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/dirinfo.html
@@ -18,6 +18,13 @@
{% load projecttags %}
<script type='text/javascript'>
+ var ctx = {};
+ ctx.target = "{{target.target}}";
+
+ $(document).ready(function(){
+ $("#menu-"+ctx.target).addClass("active");
+ });
+
function setupTreetable() {
$("#dirtable").treetable({
expandable: true,
@@ -59,9 +66,6 @@
function formatRow(o) {
/* setup tr-wide formatting */
var tr = '<tr class="';
- if (o.link_to != null) {
- tr += 'muted ';
- }
if (o.isdir && o.childcount) {
tr += 'branch" data-tt-branch="true" ';
}
@@ -75,7 +79,7 @@
tr += '>';
/* setup td specific formatting */
- var link_to = td(o.link_to);
+ var link_to = '<td class="text-muted">' + o.link_to + '</td>';
var size = '<td class = "sizecol">' + o.size + '</td>'
var permission = td(o.permission);
var owner = td(o.owner);
@@ -96,7 +100,7 @@
if (o.childcount) {
name += '<a href="">';
}
- name += '<i class="icon-folder-close"></i>';
+ name += '<span class="glyphicon glyphicon-folder-close"></span>';
name += '&nbsp;' + o.name;
if (o.childcount) {
name += '</a>';
@@ -110,10 +114,10 @@
namespan = 3;
}
var colspan = 'colspan="' + namespan + '"';
- name = '<td ' + colspan + '><i class="icon-file"></i>';
+ name = '<td ' + colspan + '><span class="glyphicon glyphicon-file"></span>';
}
else {
- name = '<td><i class="icon-hand-right"></i>';
+ name = '<td class="text-muted"><span class="glyphicon glyphicon-hand-right"></span>';
}
name += '&nbsp;' + o.name;
name += '</td>';
@@ -134,10 +138,10 @@
package += '</a>';
if (o.installed_package != o.package) {
/* make class muted and add hover help */
- package += '<span class="muted"> as ' + o.installed_package + ' </span>';
- package += '<i class="icon-question-sign get-help hover-help" ';
+ package += '<span class="text-muted"> as ' + o.installed_package + ' </span>';
+ package += '<span class="glyphicon glyphicon-question-sign get-help hover-help" ';
package += 'title="' + o.package + ' was renamed at packaging time and was installed in your image as ' + o.installed_package + '">';
- package += '</i>';
+ package += '</span>';
}
}
package = td(package);
@@ -184,22 +188,22 @@
}
</script>
-<div class="span10">
+<div class="col-md-10">
- <div class="page-header">
+ <div class="page-header build-data">
<h1> {{target.target}} </h1>
</div>
- <ul class="nav nav-pills">
- <li class="">
+ <ul class="nav nav-tabs">
+ <li>
<a href="{% url 'target' build.id target.id %}">
- <i class="icon-question-sign get-help" title="Of all the packages built, the subset installed in the root file system of this image"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Of all the packages built, the subset installed in the root file system of this image"></span>
Packages included ({{target.package_count}} - {{packages_sum|filtered_filesizeformat}})
</a>
</li>
<li class="active">
<a href="{% url 'dirinfo' build.id target.id %}">
- <i class="icon-question-sign get-help" title="The directories and files in the root file system of this image"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The directories and files in the root file system of this image"></span>
Directory structure
</a>
</li>
@@ -235,7 +239,7 @@
</tbody>
</table>
</div> <!-- directory-structure -->
-</div> <!-- span10 -->
+</div> <!-- col-md-10 -->
{% endblock buildinfomain %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html
index 8046c08fb..baa36c0e1 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/editcustomimage_modal.html
@@ -6,32 +6,36 @@ choose which one to edit
required context:
build - a Build object
-->
-<div class="modal hide fade in" aria-hidden="false" id="edit-custom-image-modal">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">Ă—</button>
- <h3>Which image do you want to edit?</h3>
- </div>
+<div class="modal fade" aria-hidden="false" id="edit-custom-image-modal">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">Ă—</button>
+ <h3>Which image do you want to edit?</h3>
+ </div>
- <div class="modal-body">
- <div class="row-fluid">
- {% for recipe in build.get_custom_image_recipes %}
- <label class="radio">
- {{recipe.name}}
- <input type="radio" class="form-control" name="select-custom-image"
- data-url="{% url 'customrecipe' build.project.id recipe.id %}">
- </label>
- {% endfor %}
- </div>
- <span class="help-block error" id="invalid-custom-image-help" style="display:none">
- Please select a custom image to edit.
- </span>
- </div>
+ <div class="modal-body">
+ {% for recipe in build.get_custom_image_recipes %}
+ <div class="radio">
+ <label>
+ <input type="radio" name="select-custom-image"
+ data-url="{% url 'customrecipe' build.project.id recipe.id %}">
+ {{recipe.name}}
+ </label>
+ </div>
+ {% endfor %}
+ <span class="help-block text-danger" id="invalid-custom-image-help" style="display:none">
+ Please select a custom image to edit.
+ </span>
+ </div>
- <div class="modal-footer">
- <button class="btn btn-primary btn-large" data-url="#"
- data-action="edit-custom-image" disabled>
- Edit custom image
- </button>
+ <div class="modal-footer">
+ <button class="btn btn-primary btn-lg" data-url="#"
+ data-action="edit-custom-image" disabled>
+ Edit custom image
+ </button>
+ </div>
+ </div>
</div>
</div>
@@ -46,7 +50,7 @@ $(document).ready(function () {
return $('[name="select-custom-image"]:checked');
};
- radios.change(function () {
+ function enableSubmit() {
if (getSelectedRadios().length === 1) {
editCustomImageButton.removeAttr('disabled');
error.hide();
@@ -55,6 +59,14 @@ $(document).ready(function () {
editCustomImageButton.attr('disabled', 'disabled');
error.show();
}
+ };
+
+ $("#edit-custom-image-modal").on("shown.bs.modal", function() {
+ enableSubmit();
+ });
+
+ radios.change(function () {
+ enableSubmit();
});
editCustomImageButton.click(function () {
@@ -67,5 +79,10 @@ $(document).ready(function () {
error.show();
}
});
+
+ // Select the first custom image listed. Radio button groups
+ // should always have an option selected by default
+ $("input:radio:first").attr("checked", "checked");
+
});
</script>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/filtersnippet.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/filtersnippet.html
index 1101aa810..1286ca315 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/filtersnippet.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/filtersnippet.html
@@ -1,57 +1,72 @@
{% load projecttags %}
<!-- '{{f.class}}' filter -->
{% with f.class as key %}
-<form id="filter_{{f.class}}" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
+
+<div id="filter_{{f.class}}" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <form>
<input type="hidden" name="search" value="{%if request.GET.search %}{{request.GET.search}}{%endif%}"/>
<div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
- {% if search_term %}
- <h3>Filter {{total_count}} {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} matching '{{search_term}}' by '{{tc.name}}'</h3>
- {% else %}
- <h3>Filter {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} by '{{tc.name}}'</h3>
- {% endif %}
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
+ {% if search_term %}
+ <h3>Filter {{total_count}} {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} matching '{{search_term}}' by '{{tc.name}}'</h3>
+ {% else %}
+ <h3>Filter {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} by '{{tc.name}}'</h3>
+ {% endif %}
</div>
<div class="modal-body">
- <p>{{f.label}}</p>
- <label class="radio">
- <input type="radio" name="filter" {%if request.GET.filter%}{{f.options|check_filter_status:request.GET.filter}} {%else%} checked {%endif%} value="" data-key="{{key}}"> All {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%}
+ <p>{{f.label}}</p>
+ <div class="radio">
+ <label>
+ <input type="radio" name="filter" {%if request.GET.filter%}{{f.options|check_filter_status:request.GET.filter}} {%else%} checked {%endif%} value="" data-key="{{key}}"> All {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%}
</label>
- {% for option in f.options %}
- {% if option.1 == 'daterange' %}
- <div class="form-inline">
- <label class="radio">
- <input type="radio" name="filter" id="filter_value_{{key}}" {%if key == daterange_selected %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}}
- {% else %}
- {% if 1 %}
- <label class="radio">
- <input type="radio" name="filter" {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}}
- {% comment "do not disable radio selections by count for now" %}{% else %}
- <label class="radio muted">
- <input type="radio" name="filter" disabled {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}}
+ </div>
+ {% for option in f.options %}
+ <div class="radio">
+ {% if option.1 == 'daterange' %}
+ <label>
+ <input type="radio" name="filter" id="filter_value_{{key}}" {%if key == daterange_selected %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}}
+ {% else %}
+ {% if 1 %}
+ <label>
+ <input type="radio" name="filter" {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}}
+ {% comment "do not disable radio selections by count for now" %}{% else %}
+ <label class="text-muted">
+ <input type="radio" name="filter" disabled {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}" data-key="{{key}}"> {{option.0}}
{% endcomment %}{% endif %}
- {% endif %}
- {% if option.3 %}<i class="icon-question-sign get-help" data-placement="right" title="{{option.3}}"></i>{% endif %}
- </label>
+ {% endif %}
+ {% if option.3 %}<i class="icon-question-sign get-help" data-placement="right" title="{{option.3}}"></i>{% endif %}
+ </label></div>
{% if option.1 == 'daterange' %}
- <input type="text" id="date_from_{{key}}" name="date_from_{{key}}" disabled class="input-small" /><label class="help-inline">to</label>
- <input type="text" id="date_to_{{key}}" name="date_to_{{key}}" disabled class="input-small" />
- <label class="help-inline get-help" >(dd/mm/yyyy)</label>
- </div>
- {% endif %}
- {% endfor %}
+ <input type="text" id="date_from_{{key}}" name="date_from_{{key}}" disabled class="input-sm" /><label class="help-inline">to</label>
+ <input type="text" id="date_to_{{key}}" name="date_to_{{key}}" disabled class="input-sm" />
+ <label class="help-inline get-help" >(dd/mm/yyyy)</label>
+ </div>
+ {% endif %}
+ {% endfor %}
<!-- daterange persistence -->
{% if last_date_from and last_date_to %}
<input type="hidden" id="last_date_from_{{key}}" name="last_date_from" value="{{last_date_from}}"/>
<input type="hidden" id="last_date_to_{{key}}" name="last_date_to" value="{{last_date_to}}"/>
{% endif %}
+ </div>
+ <div class="modal-footer">
+ <div class="row">
+ <div class="col-md-6">
+ <button type="submit" class="btn btn-primary" data-key="{{key}}">Apply</button>
</div>
- <div class="modal-footer">
- <button type="submit" class="btn btn-primary" data-key="{{key}}">Apply</button>
- {% if request.GET.filter %}
- {% if request.GET.filter|string_remove_regex:':.*' != f.options.0.1|string_remove_regex:':.*' %}
- <span class="help-inline pull-left">You can only apply one filter to the table. This filter will override the current filter.</span>
- {% endif %}
- {% endif %}
+ <div class="col-md-6">
+ {% if request.GET.filter %}
+ {% if request.GET.filter|string_remove_regex:':.*' != f.options.0.1|string_remove_regex:':.*' %}
+ <p class="text-right text-muted">You can only apply one filter to the table. This filter will override the current filter.</p>
+ {% endif %}
+ {% endif %}
</div>
-</form>
+ </div>
+ </div>
+ </form>
+ </div><!-- /.modal-content -->
+</div><!-- /.modal-dialog -->
+</div> <!--/.modal -->
{% endwith %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/generic-toastertable-page.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/generic-toastertable-page.html
index 33aa8ce0d..b3eabe1a2 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/generic-toastertable-page.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/generic-toastertable-page.html
@@ -7,7 +7,7 @@
<h2>{{title}} (<span class="table-count-{{table_name}}"></span>)
{% if project.release %}
- <i class="icon-question-sign get-help heading-help" title="This page lists {{title}} compatible with the release selected for this project, which is {{project.release.description}}"></i>
+ <i class="glyphicon glyphicon-question-sign get-help" title="This page lists {{title|lower}} compatible with the release selected for this project, which is {{project.release.description}}"></i>
{% endif %}
</h2>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/importlayer.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/importlayer.html
index 1848f410e..1f426969a 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/importlayer.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/importlayer.html
@@ -5,135 +5,163 @@
{% block title %} Import layer - {{project.name}} - Toaster {% endblock %}
{% block pagecontent %}
-{% include "projecttopbar.html" %}
-
-
- {% if project and project.release %}
- <script src="{% static 'js/layerDepsModal.js' %}"></script>
- <script src="{% static 'js/importlayer.js' %}"></script>
- <script>
- $(document).ready(function (){
- var ctx = {
- xhrImportLayerUrl : "{% url 'xhr_importlayer' %}",
- };
-
- try {
- importLayerPageInit(ctx);
- } catch (e) {
- document.write("Sorry, An error has occurred loading this page");
- console.warn(e);
- }
- });
- </script>
-
- <form class="span11">
- <fieldset>
- <legend>Layer repository information</legend>
- <span class="help-block">The layer you are importing must be compatible with <strong>{{project.release.description}}</strong>, which is the release you are using in this project.</span>
- <div class="alert alert-error" id="import-error" style="display:none">
- <button type="button" class="close" data-dismiss="alert">&times;</button>
- <h3>&nbsp;</h3>
- <p></p>
- <ul></ul>
- </div>
-
- <div class="control-group" id="layer-name-ctrl">
- <label class="control-label air" for="import-layer-name">
- Layer name
- <span class="icon-question-sign get-help" title="Something like 'meta-mylayer'. Your layer name must be unique and can only include letters, numbers and dashes"></span>
- </label>
- <div class="controls">
- <input id="import-layer-name" type="text" required autofocus data-autocomplete="off" data-provide="typeahead">
- <span class="help-inline" style="display: none;" id="invalid-layer-name-hint">A valid layer name can only include letters, numbers and dashes</span>
- <span class="help-inline" style="display: none;" id="duplicated-layer-name-hint"></span>
- </div>
-
- </div>
- <div id="duplicate-layer-info" style="display:none">
- <div class="alert warning">
- <h3>A layer called <a href="" class="dup-layer-link"><span class="dup-layer-name"></span></a> already exists</h3>
- <p>Layer names must be unqiue. Please use a different layer name.</p>
- </div>
- <dl>
- <dt>
- The <span class="dup-layer-name"></span> repository url is
- </dt>
- <dd>
- <span id="dup-layer-vcs-url"></span>
- </dd>
-
- <dt>
- The <span class="dup-layer-name"></span> revision is
- </dt>
- <dd>
- <span id="dup-layer-revision"></span>
- </dd>
- </dl>
-
- <p><a href="" class="dup-layer-link">View the <span class="dup-layer-name"></span> layer information</a></p>
-
- </div>
-
- <div class="fields-apart-from-layer-name">
- <label for="layer-git-repo-url" class="project-form">
- Git repository URL
- <span class="icon-question-sign get-help" title="Fetch/clone URL of the repository. Currently, Toaster only supports Git repositories." ></span>
- </label>
-
- <input type="text" id="layer-git-repo-url" class="input-xxlarge" required>
- <label class="project-form" for="layer-subdir">
- Repository subdirectory
- <span class="muted">(optional)</span>
- <span class="icon-question-sign get-help" title="Subdirectory within the repository where the layer is located, if not in the root (usually only used if the repository contains more than one layer)"></span>
- </label>
- <input type="text" id="layer-subdir">
-
- <div class="control-group" id="layer-revision-ctrl">
- <label class="control-label project-form" for="layer-git-ref">Git revision
- <span class="icon-question-sign get-help" title="You can provide a Git branch, a tag or a commit SHA as the revision"></span>
- </label>
- <div class="controls">
- <input type="text" class="span3" id="layer-git-ref" required>
- <span class="help-inline" style="diaply:none;" id="invalid-layer-revision-hint"></span>
- </div>
- </div>
- </div>
-
- </fieldset>
-
- <div class="fields-apart-from-layer-name">
- <fieldset class="air">
- <legend>
- Layer dependencies
- <span class="muted">(optional)</span>
- <span class="icon-question-sign get-help heading-help" title="Other layers this layer depends upon"></span>
- </legend>
- <ul class="unstyled configuration-list" id="layer-deps-list">
- </ul>
- <div class="input-append">
- <input type="text" autocomplete="off" data-minLength="1" data-autocomplete="off" data-provide="typeahead" placeholder="Type a layer name" id="layer-dependency" class="input-xlarge">
- <a class="btn" id="add-layer-dependency-btn">
- Add layer
- </a>
- </div>
- <span class="help-inline">You can only add layers Toaster knows about</span>
- </fieldset>
- <div class="air" id="form-actions">
- <button class="btn btn-primary btn-large" data-toggle="modal" id="import-and-add-btn" data-target="#dependencies-message" disabled>Import and add to project</button>
- <span class="help-inline" id="import-and-add-hint" style="vertical-align: middle;">To import a layer you need to enter a layer name, a Git repository URL and a revision (branch, tag or commit)</span>
- </div>
- </div>
- </form>
-
- {% else %} {#project and project release#}
- <div class="page-header">
- <h1>Import layer</h1>
- </div>
- <div class="alert alert-info" id="import-error" >
- <h3>Unsupported project type</h3>
- <p>This project does not support importing layers.</p>
- <ul></ul>
- </div>
-
- {% endif %}
+<div class="row">
+ {% include "projecttopbar.html" %}
+ {% if project and project.release %}
+ <script src="{% static 'js/layerDepsModal.js' %}"></script>
+ <script src="{% static 'js/importlayer.js' %}"></script>
+ <script>
+ $(document).ready(function (){
+ var ctx = {
+ xhrImportLayerUrl : "{% url 'xhr_importlayer' %}",
+ };
+
+ try {
+ importLayerPageInit(ctx);
+ } catch (e) {
+ document.write("Sorry, An error has occurred loading this page");
+ console.warn(e);
+ }
+ });
+ </script>
+
+ <form class="col-md-11">
+ <span class="help-block">The layer you are importing must be compatible with <strong>{{project.release.description}}</strong>, which is the release you are using in this project.</span>
+ <div class="alert alert-error" id="import-error" style="display:none">
+ <button type="button" class="close" data-dismiss="alert">&times;</button>
+ <h3>&nbsp;</h3>
+ <p></p>
+ <ul></ul>
+ </div>
+ <fieldset>
+ <div class="form-group" id="layer-name-ctrl">
+ <label class="control-label" for="import-layer-name">
+ Layer name
+ <span class="glyphicon glyphicon-question-sign get-help" title="Something like 'meta-mylayer'. Your layer name must be unique and can only include letters, numbers and dashes"></span>
+ </label>
+ <input class="form-control" id="import-layer-name" type="text" required autofocus data-autocomplete="off" data-provide="typeahead">
+ <span class="help-block" style="display: none;" id="invalid-layer-name-hint">A valid layer name can only include letters, numbers and dashes</span>
+ <span class="help-inline" style="display: none;" id="duplicated-layer-name-hint"></span>
+ </div>
+ </fieldset>
+ <div id="duplicate-layer-info" style="display:none">
+ <div class="alert alert-warning">
+ <h3>A layer called <a href="" class="dup-layer-link"><span class="dup-layer-name"></span></a> already exists</h3>
+ <p>Layer names must be unqiue. Please use a different layer name.</p>
+ <dl id="git-layer-dup" style="display:none;">
+ <dt>
+ The <span class="dup-layer-name"></span> repository url is
+ </dt>
+ <dd>
+ <span id="dup-layer-vcs-url"></span>
+ </dd>
+ <dt>
+ The <span class="dup-layer-name"></span> revision is
+ </dt>
+ <dd>
+ <span id="dup-layer-revision"></span>
+ </dd>
+ </dl>
+ <dl id="local-layer-dup" style="display:none;">
+ <dt>
+ The <span class="dup-layer-name"></span> directory is
+ </dt>
+ <dd>
+ <span id="dup-local-source-dir-name"></span>
+ </dd>
+ </dl>
+ <p><a href="" class="dup-layer-link">View the <span class="dup-layer-name"></span> layer information</a></p>
+ </div>
+ </div>
+ <fieldset class="fields-apart-from-layer-name" id="repo-select">
+ <legend class="radioLegend">Where is the layer source code?</legend>
+ <div class="radio">
+ <label>
+ <input type="radio" id="git-repo-radio" name="repo" value="git" checked="checked">
+ In a <strong>Git repository</strong>
+ </label>
+ <p class="help-block radio-help">To build the layer Toaster must be able to access the Git repository, otherwise builds will fail. Toaster will fetch and checkout your chosen Git revision every time you start a build.</p>
+ </div>
+ <div class="radio">
+ <label>
+ <input type="radio" id="local-dir-radio" name="repo" value="local">
+ In a <strong>directory</strong>
+ </label>
+ <p class="help-block radio-help">Use this option for quick layer development, by simply providing the path to the layer source code.</p>
+ </div>
+ </fieldset>
+ <fieldset class="fields-apart-from-layer-name" id="git-repo">
+ <legend>Git repository information</legend>
+ <div class="form-group">
+ <label for="layer-git-repo-url">
+ Git repository URL
+ <span class="glyphicon glyphicon-question-sign get-help" title="Fetch/clone URL of the repository. Currently, Toaster only supports Git repositories." ></span>
+ </label>
+ <input type="text" id="layer-git-repo-url" class="form-control" required>
+ </div>
+ <div class="form-group">
+ <label for="layer-subdir">
+ Repository subdirectory
+ <span class="text-muted">(optional)</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Subdirectory within the repository where the layer is located, if not in the root (usually only used if the repository contains more than one layer)"></span>
+ </label>
+ <input type="text" class="form-control" id="layer-subdir">
+ </div>
+ <div class="form-group" id="layer-revision-ctrl">
+ <label for="layer-git-ref">
+ Git revision
+ <span class="glyphicon glyphicon-question-sign get-help" title="You can provide a Git branch, a tag or a commit SHA as the revision"></span>
+ </label>
+ <input type="text" class="form-control" id="layer-git-ref" required>
+ <span class="help-inline" style="display:none;" id="invalid-layer-revision-hint"></span>
+ </div>
+ </fieldset>
+
+ <fieldset class="fields-apart-from-layer-name" id="local-dir" style="display:none;">
+ <legend>Layer directory information</legend>
+ <div class="form-group">
+ <label for="local-dir-path" class="control-label">Enter the absolute path to the layer directory</label>
+ <input type="text" class="form-control" id="local-dir-path" required/>
+ <p class="help-block" id="hintError-dir-path-starts-with-slash" style="display:none;">The absolute path must start with "/".</p>
+ <p class="help-block" id="hintError-dir-path" style="display:none;">The directory path cannot include spaces or any of these characters: . \ ? % * : | " " &lt; &gt;</p>
+ </div>
+ </fieldset>
+
+ <fieldset class="fields-apart-from-layer-name">
+ <legend>
+ Layer dependencies
+ <small class="text-muted">(optional)</small>
+ <span class="glyphicon glyphicon-question-sign get-help heading-help" title="Other layers this layer depends upon"></span>
+ </legend>
+ <ul class="list-unstyled lead" id="layer-deps-list">
+ </ul>
+ <div class="form-inline">
+ <div class="form-group">
+ <input type="text" autocomplete="off" data-minLength="1" data-autocomplete="off" data-provide="typeahead" placeholder="Type a layer name" id="layer-dependency" class="form-control">
+ </div>
+ <button class="btn btn-default" id="add-layer-dependency-btn">
+ Add layer
+ </button>
+ <span class="help-inline">You can only add layers Toaster knows about</span>
+ </fieldset>
+ <div class="top-air fields-apart-from-layer-name" id="form-actions">
+ <button class="btn btn-primary btn-lg" data-toggle="modal" id="import-and-add-btn" data-target="#dependencies-message" disabled>Import and add to project</button>
+ <span class="help-inline" id="import-git-layer-and-add-hint" style="vertical-align: middle;">To import a layer you need to enter a layer name, a Git repository URL and a Git revision (branch, tag or commit)</span>
+ <span class="help-inline" id="import-local-dir-and-add-hint" style="vertical-align: middle;display:none;">To import a layer you need to enter a layer name and the absolute path to the layer directory</span>
+ </div>
+ </div>
+</form>
+
+ {% else %} {#project and project release#}
+ <div class="page-header">
+ <h1>Import layer</h1>
+ </div>
+ <div class="alert alert-info" id="import-error" >
+ <h3>Unsupported project type</h3>
+ <p>This project does not support importing layers.</p>
+ <ul></ul>
+ </div>
+
+ {% endif %}
+</div>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing.html
index a1b5cdce7..498663294 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing.html
@@ -6,24 +6,22 @@
{% block title %} Welcome to Toaster {% endblock %}
{% block pagecontent %}
- <div class="container-fluid">
- <div class="row-fluid">
- <div class="hero-unit span12 well-transparent">
- <div class="row-fluid">
+ <div class="row">
+ <div class="jumbotron well-transparent">
- <div class="span6">
+ <div class="col-md-6">
<h1>This is Toaster</h1>
<p>A web interface to <a href="http://www.openembedded.org">OpenEmbedded</a> and <a href="http://www.yoctoproject.org/tools-resources/projects/bitbake">BitBake</a>, the <a href="http://www.yoctoproject.org">Yocto Project</a> build system.</p>
{% if lvs_nos %}
- <p class="hero-actions">
- <a class="btn btn-primary btn-large" href="{% url 'newproject' %}">
+ <p class="top-air">
+ <a class="btn btn-primary btn-lg" href="{% url 'newproject' %}">
To start building, create your first Toaster project
</a>
</p>
{% else %}
- <div class="alert alert-info lead air">
+ <div class="alert alert-info lead top-air">
Toaster has no layer information. Without layer information, you cannot run builds. To generate layer information you can:
<ul>
<li>
@@ -36,7 +34,7 @@
</div>
{% endif %}
- <ul class="unstyled">
+ <ul class="list-unstyled lead">
<li>
<a href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html">
Read the Toaster manual
@@ -51,12 +49,11 @@
</ul>
</div>
- <div class="span6">
- <img alt="Yocto Project" class="thumbnail" src="{% static 'img/toaster_bw.png' %}"/>
+ <div class="col-md-6">
+ <img alt="Yocto Project Toaster" class="img-thumbnail" src="{% static 'img/toaster_bw.png' %}"/>
</div>
- </div>
</div>
</div>
- </div>
+
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing_not_managed.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing_not_managed.html
index 9b37f5530..baa4b72c1 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing_not_managed.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/landing_not_managed.html
@@ -8,8 +8,8 @@
{% block pagecontent %}
- <div class="container-fluid">
- <div class="row-fluid">
+ <div class="container">
+ <div class="row">
<!-- Empty - no build module -->
<div class="page-header top-air">
<h1>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layer_btn.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layer_btn.html
index 10de37d4b..b2f73eba7 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layer_btn.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layer_btn.html
@@ -1,17 +1,17 @@
-<button class="btn btn-danger btn-block layer-exists-{{data.pk}} layerbtn" data-layer='{ "id": {{data.pk}}, "name": "{{data.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.pk%}"}' data-directive="remove"
+<a class="btn btn-danger btn-block layer-exists-{{data.pk}} layerbtn" data-layer='{ "id": {{data.pk}}, "name": "{{data.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.pk%}"}' data-directive="remove"
{% if data.pk not in extra.current_layers %}
style="display:none;"
{% endif %}
>
- <i class="icon-trash"></i>
+ <span class="glyphicon glyphicon-trash"></span>
Remove layer
-</button>
-<button class="btn btn-block layer-add-{{data.pk}} layerbtn" data-layer='{ "id": {{data.pk}}, "name": "{{data.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.pk%}"}' data-directive="add"
+</a>
+<a class="btn btn-default btn-block layer-add-{{data.pk}} layerbtn" data-layer='{ "id": {{data.pk}}, "name": "{{data.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.pk%}"}' data-directive="add"
{% if data.pk in extra.current_layers %}
style="display:none;"
{% endif %}
>
- <i class="icon-plus"></i>
+ <span class="glyphicon glyphicon-plus"></span>
Add layer
-</button>
+</a>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layerdetails.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layerdetails.html
index 82be3703b..f1569bd63 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layerdetails.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/layerdetails.html
@@ -6,270 +6,367 @@
{% block title %} {{layerversion.layer.name}} - {{project.name}} - Toaster {% endblock %}
{% block pagecontent %}
-<div class="section">
- <ul class="breadcrumb">
- <li>
- <a href="{% url 'project' project.id %}">{{project.name}}</a>
- <span class="divider">&rarr;</span>
- </li>
- <li><a href="{% url 'projectlayers' project.id %}">Compatible layers</a>
- <span class="divider">&rarr;</span>
- </li>
- <li class="active">
- {{layerversion.layer.name}} ({{layerversion.get_vcs_reference|truncatechars:13}})
- </li>
- </ul>
+<div id="delete-layer-modal" class="modal fade" tabindex="-1" role="dialog"
+ data-keyboard="false" data-backdrop="static">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-body">
+ Are you sure you want to delete the <strong>{{layerversion.layer.name}}</strong> layer?
+ </div>
+ <div class="modal-footer">
+ <button type="button" id="layer-delete-confirmed" class="btn
+ btn-primary">Delete layer</button>
+ <button type="button" class="btn btn-default btn-link" data-dismiss="modal">Cancel</button>
+ </div>
+ </div>
+ </div>
</div>
-{# If this is not an imported layer then hide the edit ui #}
-{% if not layerversion.layer_source_id or layerversion.layer_source.sourcetype != layerversion.layer_source.TYPE_IMPORTED %}
-<style scoped>
- .icon-pencil {
- display:none;
- }
-.delete-current-value{
- display: none;
-}
- li .icon-trash {
- display:none;
- }
- .add-deps {
- display:none;
- }
-</style>
-{% endif %}
-
+<div class="row">
+ <div class="col-md-12">
+ <ul class="breadcrumb">
+ <li>
+ <a href="{% url 'project' project.id %}">{{project.name}}</a>
+ <span class="divider">&rarr;</span>
+ </li>
+ <li><a href="{% url 'projectlayers' project.id %}">Compatible layers</a>
+ <span class="divider">&rarr;</span>
+ </li>
+ <li class="active">
+ {{layerversion.layer.name}} ({{layerversion.get_vcs_reference|truncatechars:13}})
+ </li>
+ </ul>
-<script src="{% static 'js/layerdetails.js' %}"></script>
-<script>
+ {# If this is not an imported layer then hide the edit ui #}
+ {% if layerversion.layer_source != layer_source.TYPE_IMPORTED %}
+ <style scoped>
+ .glyphicon-edit {
+ display:none;
+ }
+ .delete-current-value{
+ display: none;
+ }
+ li .glyphicon-trash {
+ display:none;
+ }
+ .add-deps {
+ display:none;
+ }
+ </style>
+ {% endif %}
- $(document).ready(function (){
- var ctx = {
- xhrUpdateLayerUrl : "{% url 'xhr_updatelayer' %}",
- layerVersion : {
- name : "{{layerversion.layer.name}}",
- id : {{layerversion.id}},
- commit: "{{layerversion.get_vcs_reference}}",
- {%if layerversion.id in projectlayers %}
- inCurrentPrj : true,
- {% else %}
- inCurrentPrj : false,
- {% endif %}
- layerdetailurl : "{% url 'layerdetails' project.id layerversion.id %}",
- sourceId: {{layerversion.layer_source_id|json}},
- }
- };
+ <script src="{% static 'js/layerdetails.js' %}"></script>
+ <script>
- try {
- layerDetailsPageInit(ctx);
- } catch (e) {
- document.write("Sorry, An error has occurred loading this page");
- console.warn(e);
- }
- });
-</script>
+ $(document).ready(function(){
+ var ctx = {
+ xhrUpdateLayerUrl : "{% url 'xhr_layer' project.id layerversion.pk %}",
+ layerVersion : {
+ name : "{{layerversion.layer.name}}",
+ id : {{layerversion.id}},
+ commit: "{{layerversion.get_vcs_reference}}",
+ {%if layerversion.id in projectlayers %}
+ inCurrentPrj : true,
+ {% else %}
+ inCurrentPrj : false,
+ {% endif %}
+ layerdetailurl : "{% url 'layerdetails' project.id layerversion.id %}",
+ layer_source: {{layerversion.layer_source|json}},
+ },
+ layerSourceTypes: {{layer_source|json}},
+ };
-<div class="row-fluid span11">
- <div class="page-header">
- <h1>{{layerversion.layer.name}} <small class="commit"
- {% if layerversion.get_vcs_reference|length > 13 %}
- data-toggle="tooltip" title="{{layerversion.get_vcs_reference}}"
- {% endif %}>
- ({{layerversion.get_vcs_reference|truncatechars:13}})</small></h1>
- </div>
-</div>
+ try {
+ layerDetailsPageInit(ctx);
+ } catch (e) {
+ document.write("Sorry, An error has occurred loading this page");
+ console.warn(e);
+ }
+ });
+ </script>
-<!-- container for tabs -->
-<div class="row-fluid span7 tabbable">
- <div class="alert alert-info lead" id="alert-area" style="display:none">
- <button type="button" class="close" id="dismiss-alert">&times;</button>
- <span id="alert-msg"></span>
- </div>
- <ul class="nav nav-pills">
- <li class="active">
- <a data-toggle="tab" href="#information" id="details-tab">Layer details</a>
- </li>
- <li>
- <a data-toggle="tab" href="#recipes" class="muted" id="targets-tab">Recipes (<span class="table-count-recipestable"></span>)</a>
- </li>
- <li>
- <a data-toggle="tab" href="#machines" class="muted" id="machines-tab">Machines (<span class="table-count-machinestable"></span>)</a>
- </li>
- </ul>
- <div class="tab-content">
- <span class="button-place">
- {% if layerversion.id not in projectlayers %}
- <button id="add-remove-layer-btn" data-directive="add" class="btn btn-large btn-block">
- <span class="icon-plus"></span>
- Add the {{layerversion.layer.name}} layer to your project
- </button>
+ <div class="page-header">
+ {% if layerversion.layer.local_source_dir %}
+ <h1>{{layerversion.layer.name}} <small class="commit" style="display:none;"></small>
+ </h1>
{% else %}
- <button id="add-remove-layer-btn" data-directive="remove" class="btn btn-block btn-large btn-danger">
- <span class="icon-trash"></span>
- Remove the {{layerversion.layer.name}} layer from your project
- </button>
+ <h1>{{layerversion.layer.name}} <small class="commit"
+ {% if layerversion.get_vcs_reference|length > 13 %}
+ data-toggle="tooltip" title="{{layerversion.get_vcs_reference}}"
+ {% endif %}>({{layerversion.get_vcs_reference|truncatechars:13}})</small>
+ </h1>
{% endif %}
- </span>
+ </div>
+ <div class="row">
+ <!-- container for tabs -->
+ <div class="col-md-8 tabbable">
+ <div class="alert alert-info lead" id="alert-area" style="display:none">
+ <button type="button" class="close" id="dismiss-alert">&times;</button>
+ <span id="alert-msg"></span>
+ </div>
- <!-- layer details pane -->
- <div id="information" class="tab-pane active">
- <dl class="dl-horizontal">
- <dt class="">
- <i class="icon-question-sign get-help" title="Fetch/clone URL of the repository"></i>
- Repository URL
- </dt>
- <dd>
- <span class="current-value">{{layerversion.layer.vcs_url}}</span>
- {% if layerversion.get_vcs_link_url %}
- <a href="{{layerversion.get_vcs_link_url}}/" class="icon-share get-info" target="_blank"></a>
- {% endif %}
- <form id="change-repo-form" class="control-group" style="display:none">
- <div class="input-append">
- <input type="text" class="input-xlarge" value="{{layerversion.layer.vcs_url}}">
- <button data-layer-prop="vcs_url" class="btn change-btn" type="button">Save</button>
- <a href="#" style="display:none" class="btn btn-link cancel">Cancel</a>
- </div>
- </form>
- <i class="icon-pencil" ></i>
- </dd>
- <dt>
- <i class="icon-question-sign get-help" title="Subdirectory within the repository where the layer is located, if not in the root (usually only used if the repository contains more than one layer)"></i>
- Repository subdirectory
- </dt>
- <dd>
- <span class="muted" style="display:none">Not set</span>
- <span class="current-value">{{layerversion.dirpath}}</span>
- {% if layerversion.get_vcs_dirpath_link_url %}
- <a href="{{layerversion.get_vcs_dirpath_link_url}}" class="icon-share get-info" target="_blank"></a>
- {% endif %}
- <form id="change-subdir-form" style="display:none;">
- <div class="input-append">
- <input type="text" value="{{layerversion.dirpath}}">
- <button data-layer-prop="dirpath" class="btn change-btn" type="button">Save</button>
- <a href="#" style="display:none" class="btn btn-link cancel">Cancel</a>
+ {% if layerversion.id not in projectlayers %}
+ <button id="add-remove-layer-btn" data-directive="add" class="btn btn-default btn-lg btn-block">
+ <span class="glyphicon glyphicon-plus"></span>
+ Add the {{layerversion.layer.name}} layer to your project
+ </button>
+ {% else %}
+ <button id="add-remove-layer-btn" data-directive="remove" class="btn btn-default btn-block btn-lg btn-danger">
+ <span class="glyphicon glyphicon-trash"></span>
+ Remove the {{layerversion.layer.name}} layer from your project
+ </button>
+ {% endif %}
+
+ <ul class="nav nav-tabs">
+ <li class="active">
+ <a data-toggle="tab" href="#information" id="details-tab">Layer details</a>
+ </li>
+ <li>
+ <a data-toggle="tab" href="#recipes" class="text-muted" id="targets-tab">Recipes (<span class="table-count-recipestable"></span>)</a>
+ </li>
+ <li>
+ <a data-toggle="tab" href="#machines" class="text-muted" id="machines-tab">Machines (<span class="table-count-machinestable"></span>)</a>
+ </li>
+ </ul>
+ <div class="tab-content">
+
+ <!-- layer details pane -->
+ <div id="information" class="tab-pane active">
+ <h3>Layer source code location</h3>
+ {% if layerversion.layer.local_source_dir %}
+ <dl class="dl-horizontal" id="directory-info">
+ <dt>
+ Path to the layer directory
+ </dt>
+ <dd>
+ <code>{{layerversion.layer.local_source_dir}}</code>
+ </dd>
+ </dl>
+ {% else %}
+ <dl class="dl-horizontal" id="git-repo-info">
+ <dt class="">
+ <span class="glyphicon glyphicon-question-sign get-help" title="Fetch/clone URL of the repository"></span>
+ Repository URL
+ </dt>
+ <dd>
+ <span class="current-value">{{layerversion.layer.vcs_url}}</span>
+ {% if layerversion.get_vcs_link_url %}
+ <a href="{{layerversion.get_vcs_link_url}}/" class="glyphicon glyphicon-new-window" target="_blank"></a>
+ {% endif %}
+ <form id="change-repo-form" class="form-inline" style="display:none">
+ <div class="form-group">
+ <input type="text" class="form-control" value="{{layerversion.layer.vcs_url}}">
</div>
</form>
- <i id="change-subdir" class="icon-pencil"></i>
- <span class="icon-trash delete-current-value" data-toggle="tooltip" title="Delete"></span>
- </dd>
- <dt>
- <i class="icon-question-sign get-help" title="The Git branch, tag or commit"></i>
- Git revision
- </dt>
- <dd>
- <span class="current-value">{{layerversion.get_vcs_reference}}</span>
- <form style="display:none;">
- <div class="input-append">
- <input type="text" value="{{layerversion.get_vcs_reference}}">
- <button data-layer-prop="commit" class="btn change-btn" type="button">Save</button>
- <a href="#" style="display:none" class="btn btn-link cancel">Cancel</a>
- </div>
- </form>
- <i class="icon-pencil"></i>
</dd>
+ {% if layerversion.dirpath %}
<dt>
- <i class="icon-question-sign get-help" title="Other layers this layer depends upon"></i>
- Layer dependencies
+ <span class="glyphicon glyphicon-question-sign get-help" title="Subdirectory within the repository where the layer is located, if not in the root (usually only used if the repository contains more than one layer)"></span>
+ Repository subdirectory
</dt>
<dd>
- <ul class="unstyled current-value" id="layer-deps-list">
- {% for ld in layerversion.dependencies.all %}
- <li data-layer-id="{{ld.depends_on.id}}">
- <a data-toggle="tooltip" title="{{ld.depends_on.layer.vcs_url}} | {{ld.depends_on.get_vcs_reference}}" href="{% url 'layerdetails' project.id ld.depends_on.id %}">{{ld.depends_on.layer.name}}</a>
- <span class="icon-trash " data-toggle="tooltip" title="Delete"></span>
- </li>
- {% endfor %}
- </ul>
- <div class="input-append add-deps">
- <input type="text" autocomplete="off" data-minLength="1" data-autocomplete="off" placeholder="Type a layer name" id="layer-dep-input">
- <a class="btn" id="add-layer-dependency-btn" >
- Add layer
- </a>
- </div>
- <span class="help-block add-deps">You can only add layers Toaster knows about</span>
- </dd>
- </dl>
- </div>
- <!-- end layerdetails tab -->
- <!-- targets tab -->
- <div id="recipes" class="tab-pane">
- <!-- Recipe table -->
- <div id="no-recipes-yet" class="alert alert-info" style="display:none">
- <p>Toaster does not have recipe information for the <strong> {{layerversion.layer.name}} </strong> layer.</p>
- <p>Toaster learns about layers when you build them. If this layer provides any recipes, they will be listed here after you build the <strong> {{layerversion.layer.name}} </strong> layer.</p>
- </div>
+ <span class="text-muted" style="display:none">Not set</span>
+ <span class="current-value">{{layerversion.dirpath}}</span>
+ {% if layerversion.get_vcs_dirpath_link_url %}
+ <a href="{{layerversion.get_vcs_dirpath_link_url}}" class="glyphicon glyphicon-new-window" target="_blank"></a>
+ {% endif %}
+ <form id="change-subdir-form" class="form-inline" style="display:none;">
+ <div class="form-group">
+ <input type="text" class="form-control" value="{{layerversion.dirpath}}">
+ </div>
+ </form>
+ </dd>
+ {% endif %}
+ <dt>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The Git branch, tag or commit"></span>
+ Git revision
+ </dt>
+ <dd>
+ <span class="current-value">{{layerversion.get_vcs_reference}}</span>
+ <form style="display:none;" class="form-inline">
+ <div class="form-group">
+ <input type="text" class="form-control" value="{{layerversion.get_vcs_reference}}">
+ </div>
+ </form>
+ </dd>
+ </dl>
+ {% endif %}
+ {% if layerversion.layer_source == layer_source.TYPE_IMPORTED %}
+ <button class="btn btn-default btn-lg" id="edit-layer-source" style="margin-left:220px;">Edit layer source code location</button>
+ {% endif %}
+ <form id="edit-layer-source-form" style="display:none;">
+ <fieldset>
+ <legend class="radioLegend">Where is the layer source code?</legend>
+ <div class="radio">
+ <label>
+ <input type="radio" name="source-location" id="repo" value="repo">
+ In a <strong>Git repository</strong>
+ </label>
+ <p class="help-block" style="margin-left:20px;width:70%;">To build the layer Toaster must be able to access the Git repository, otherwise builds will fail. Toaster will fetch and checkout your chosen Git revision every time you start a build.</p>
+ </div>
+ <div class="radio" style="margin-top:15px;">
+ <label>
+ <input type="radio" name="source-location" id="dir" value="dir" checked>
+ In a <strong>directory</strong>
+ </label>
+ <p class="help-block" style="margin-left:20px;width:70%;">Use this option for quick layer development, by simply providing the path to the layer source code.</p>
+ </div>
+ </fieldset>
+ <fieldset id="layer-git">
+ <legend>Git repository information</legend>
+ <div class="form-group">
+ <label for="layer-git-repo-url">
+ Git repository URL
+ <span class="glyphicon glyphicon-question-sign get-help" title="Fetch/clone URL of the repository. Currently, Toaster only supports Git repositories." ></span>
+ </label>
+ <input type="text" id="layer-git-repo-url" class="form-control" value="{{layerversion.layer.vcs_url|default_if_none:''}}">
+ </div>
+ <div class="form-group">
+ <label for="layer-subdir">
+ Repository subdirectory
+ <span class="text-muted">(optional)</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Subdirectory within the repository where the layer is located, if not in the root (usually only used if the repository contains more than one layer)"></span>
+ </label>
+ <input type="text" class="form-control" id="layer-subdir" value="{{layerversion.dirpath|default_if_none:''}}">
+ </div>
+ <div class="form-group" id="layer-revision-ctrl">
+ <label for="layer-git-ref">Git revision
+ <span class="glyphicon glyphicon-question-sign get-help" title="You can provide a Git branch, a tag or a commit SHA as the revision"></span>
+ </label>
+ <input type="text" class="form-control" id="layer-git-ref" value="{{layerversion.get_vcs_reference|default_if_none:''}}">
+ <span class="help-inline" style="display:none;" id="invalid-layer-revision-hint"></span>
+ </div>
+ </fieldset>
+ <fieldset id="layer-dir">
+ <legend>Layer directory information</legend>
+ <div class="form-group">
+ <label for="layer-dir-path">
+ Enter the absolute path to the layer directory
+ </label>
+ <input type="text" id="layer-dir-path-in-details" class="form-control" value="{{layerversion.layer.local_source_dir}}" required>
+ </div>
+ </fieldset>
- {% url 'layerrecipestable' project.id layerversion.id as xhr_table_url %}
- {% with "recipestable" as table_name %}
- {% with "Recipes" as title %}
- {% include 'toastertable-simple.html' %}
- {% endwith %}
- {% endwith %}
- </div>
+ <div style="margin-top:25px;">
+ <a href="#" class="btn btn-primary btn-lg" id="save-changes-for-switch">Save changes</a>
+ <a href="#" class="btn btn-link btn-lg" id="cancel-changes-for-switch">Cancel</a>
+ </div>
+ </form>
- <div id="machines" class="tab-pane">
+ <h3 class="top-air">Layer dependencies
+ <span class="glyphicon glyphicon-question-sign get-help" title="Other layers this layer depends upon"></span>
+ </h3>
- <div id="no-machines-yet" class="alert alert-info" style="display:none">
- <p>Toaster does not have machine information for the <strong> {{layerversion.layer.name}} </strong> layer.</p>
- <p>Toaster learns about layers when you build them. If this layer provides any machines, they will be listed here after you build the <strong> {{layerversion.layer.name}} </strong> layer.</p>
- </div>
+ <ul class="list-unstyled current-value lead" id="layer-deps-list">
+ {% for ld in layerversion.dependencies.all %}
+ <li data-layer-id="{{ld.depends_on.id}}">
+ <a data-toggle="tooltip" title="{{ld.depends_on.layer.vcs_url}} | {{ld.depends_on.get_vcs_reference}}" href="{% url 'layerdetails' project.id ld.depends_on.id %}">{{ld.depends_on.layer.name}}</a>
+ <span class="glyphicon glyphicon-trash " data-toggle="tooltip" title="Delete"></span>
+ </li>
+ {% endfor %}
+ </ul>
+ <form class="form-inline add-deps">
+ <div class="form-group">
+ <input class="form-control" type="text" autocomplete="off" data-minLength="1" data-autocomplete="off" placeholder="Type a layer name" id="layer-dep-input">
+ </div>
+ <a class="btn btn-default" id="add-layer-dependency-btn" disabled="disabled">
+ Add layer
+ </a>
+ <span class="help-block add-deps">You can only add layers Toaster knows about</span>
+ </form>
+ </div>
+ <!-- end layerdetails tab -->
+ <!-- targets tab -->
+ <div id="recipes" class="tab-pane">
+ <!-- Recipe table -->
+ <div id="no-recipes-yet" class="alert alert-info" style="display:none">
+ <p>Toaster does not have recipe information for the <strong> {{layerversion.layer.name}} </strong> layer.</p>
+ <p>Toaster learns about layers when you build them. If this layer provides any recipes, they will be listed here after you build the <strong> {{layerversion.layer.name}} </strong> layer.</p>
+ </div>
+ {% url 'layerrecipestable' project.id layerversion.id as xhr_table_url %}
+ {% with "recipestable" as table_name %}
+ {% with "Recipes" as title %}
+ {% include 'toastertable-simple.html' %}
+ {% endwith %}
+ {% endwith %}
+ </div>
+ <div id="machines" class="tab-pane">
- <!-- Machines table -->
- {% url 'layermachinestable' project.id layerversion.id as xhr_table_url %}
- {% with "machinestable" as table_name %}
- {% with "Machines" as title %}
- {% include 'toastertable-simple.html' %}
- {% endwith %}
- {% endwith %}
+ <div id="no-machines-yet" class="alert alert-info" style="display:none">
+ <p>Toaster does not have machine information for the <strong> {{layerversion.layer.name}} </strong> layer.</p>
+ <p>Sadly, machine information cannot be obtained from builds, so this page will remain empty.</p>
</div>
- </div> <!-- end tab content -->
- </div> <!-- end tabable -->
- <div class="row-fluid span4 well"> <!-- info side panel -->
+
+ <!-- Machines table -->
+ {% url 'layermachinestable' project.id layerversion.id as xhr_table_url %}
+ {% with "machinestable" as table_name %}
+ {% with "Machines" as title %}
+ {% include 'toastertable-simple.html' %}
+ {% endwith %}
+ {% endwith %}
+ </div>
+ </div> <!-- end tab content -->
+ </div> <!-- end tabable -->
+
+ <div class="col-md-4"> <!-- info side panel -->
+ <div class="well">
<h2>About {{layerversion.layer.name}}</h2>
<dl class="item-info">
<dt>
- Summary
- <i class="icon-question-sign get-help" title="One-line description of the layer"></i>
+ Summary
+ <span class="glyphicon glyphicon-question-sign get-help" title="One-line description of the layer"></span>
</dt>
<dd>
- <span class="muted" style="display:none">Not set</span>
- <span class="current-value">{{layerversion.layer.summary|default_if_none:''}}</span>
- <form style="display:none; margin-bottom:20px">
- <textarea class="span12" rows="2">{% if layerversion.layer.summary %}{{layerversion.layer.summary}}{% endif %}</textarea>
- <button class="btn change-btn" data-layer-prop="summary" type="button">Save</button>
- <a href="#" class="btn btn-link cancel">Cancel</a>
- </form>
- <i class="icon-pencil"></i>
- <span class="icon-trash delete-current-value" data-toggle="tooltip" title="Delete"></span>
+ <span class="text-muted" style="display:none">Not set</span>
+ <span class="current-value">{{layerversion.layer.summary|default_if_none:''}}</span>
+ <form style="display:none; margin-bottom:20px; margin-top:5px;">
+ <div class="form-group">
+ <textarea class="form-control" rows="2">{% if layerversion.layer.summary %}{{layerversion.layer.summary}}{% endif %}</textarea>
+ </div>
+ <button class="btn btn-default change-btn" data-layer-prop="summary" type="button">Save</button>
+ <a href="#" class="btn btn-link cancel">Cancel</a>
+ </form>
+ <span class="glyphicon glyphicon-edit"></span>
+ <span class="glyphicon glyphicon-trash delete-current-value" data-toggle="tooltip" title="Delete"></span>
</dd>
<dt>
- Description
+ Description
</dt>
<dd>
- <span class="muted" style="display:none">Not set</span>
- <span class="current-value">{{layerversion.layer.description|default_if_none:''}}</span>
- <form style="display:none; margin-bottom:20px">
- <textarea class="span12" rows="6">{% if layerversion.layer.description %}{{layerversion.layer.description}}{% endif %}</textarea>
- <button class="btn change-btn" data-layer-prop="description" type="button" >Save</button>
- <a href="#" class="btn btn-link cancel">Cancel</a>
- </form>
- <i class="icon-pencil"></i>
- <span class="icon-trash delete-current-value" data-toggle="tooltip" title="Delete"></span>
+ <span class="text-muted" style="display:none">Not set</span>
+ <span class="current-value">{{layerversion.layer.description|default_if_none:''}}</span>
+ <form style="display:none; margin-bottom:20px; margin-top:5px;">
+ <div class="form-group">
+ <textarea class="form-control" rows="6">{% if layerversion.layer.description %}{{layerversion.layer.description}}{% endif %}</textarea>
+ </div>
+ <button class="btn btn-default change-btn" data-layer-prop="description" type="button" >Save</button>
+ <a href="#" class="btn btn-link cancel">Cancel</a>
+ </form>
+ <span class="glyphicon glyphicon-edit"></span>
+ <span class="glyphicon glyphicon-trash delete-current-value" data-toggle="tooltip" title="Delete"></span>
</dd>
- {% if layerversion.layer.up_id %}
+ {% if layerversion.layer_source == layer_source.TYPE_LAYERINDEX %}
<dt>Layer index</dt>
<dd>
- <a href="http://layers.openembedded.org/layerindex/branch/{{layerversion.up_branch.name}}/layer/{{layerversion.layer.name}}">layer index link</a>
-
- </dd>
+ <a href="http://layers.openembedded.org/layerindex/branch/{{layerversion.release.name}}/layer/{{layerversion.layer.name}}">Layer index {{layerversion.layer.name}}</a>
+ </dd>
+ {% endif %}
+ </dl>
+ {# Only show delete link for imported layers #}
+ {% if layerversion.layer_source == layer_source.TYPE_IMPORTED %}
+ <i class="icon-trash text-danger"></i>
+ <a href="#delete-layer-modal" role="button" class="text-danger"
+ data-toggle="modal" data-target="#delete-layer-modal">Delete layer</a>
{% endif %}
-
- </dl>
+ </div>
</div>
+ </div>
+ </div> <!-- close column 12 div -->
+</div> <!-- close top row div -->
- {% endblock %}
+{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/machine_btn.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/machine_btn.html
index 7b08f6a9a..5d93d7aa9 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/machine_btn.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/machine_btn.html
@@ -1,16 +1,16 @@
-<a href="{% url 'project' extra.pid %}?setMachine={{data.name}}" class="btn btn-block layer-exists-{{data.layer_version.id}}"
+<a href="{% url 'project' extra.pid %}?setMachine={{data.name}}" class="btn btn-default btn-block layer-exists-{{data.layer_version.id}}"
{% if data.layer_version.pk not in extra.current_layers %}
style="display:none;"
{% endif %}
>
Select machine</a>
-<button class="btn btn-block layerbtn layer-add-{{data.layer_version.id}}" data-layer='{ "id": {{data.layer_version.id}}, "name": "{{data.layer_version.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.id %}"}' data-directive="add"
+<a class="btn btn-default btn-block layerbtn layer-add-{{data.layer_version.id}}" data-layer='{ "id": {{data.layer_version.id}}, "name": "{{data.layer_version.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.id %}"}' data-directive="add"
{% if data.layer_version.pk in extra.current_layers %}
style="display:none;"
{% endif %}
>
- <i class="icon-plus"></i>
+ <span class="glyphicon glyphicon-plus"></span>
Add layer
- <i title="" class="icon-question-sign get-help" data-original-title="To enable this machine, you must first add the {{data.layer_version.layer.name}} layer to your project"></i>
-</button>
+ <span class="glyphicon glyphicon-question-sign get-help" title="To select this machine, you must first add the {{data.layer_version.layer.name}} layer to your project"></i>
+</a>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/mrb_section.html
index b5e798d7c..b761ffe1d 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/mrb_section.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/mrb_section.html
@@ -1,178 +1,274 @@
{% load static %}
-{% load projecttags %}
-{% load project_url_tag %}
{% load humanize %}
+{% load project_url_tag %}
<script src="{% static 'js/mrbsection.js' %}"></script>
-<script>
- $(document).ready(function () {
- var ctx = {
- mrbType : "{{mrb_type}}",
- }
- try {
- mrbSectionInit(ctx);
- } catch (e) {
- document.write("Sorry, An error has occurred loading this page");
- console.warn(e);
- }
- });
-</script>
-
-{%if mru and mru.count > 0%}
-
- {%if mrb_type == 'project' %}
- <h2 class="page-header">
+{% if mru %}
+ {% if mrb_type == 'project' %}
+ <h2>
Latest project builds
{% if project.is_default %}
- <i class="icon-question-sign get-help heading-help" title="" data-original-title="Builds in this project cannot be started from Toaster: they are started from the command line"></i>
- {% endif %}
- </h2>
+ <span class="glyphicon glyphicon-question-sign get-help heading-help" data-original-title="Builds in this project cannot be started from Toaster: they are started from the command line"></span>
+ {% endif %}
+ </h2>
{% else %}
- <div class="page-header top-air">
- <h1>
- Latest builds
- </h1>
+ <div class="page-header">
+ <h1>Latest builds</h1>
</div>
{% endif %}
+
<div id="latest-builds">
- {% for build in mru %}
- <div data-latest-build-result="{{ build.id }}" class="alert build-result {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}{% if mrb_type != 'project' %} project-name{% endif %}">
- {% if mrb_type != 'project' %}
- <span class="label {%if build.outcome == build.SUCCEEDED%}label-success{%elif build.outcome == build.FAILED%}label-important{%else%}label-info{%endif%}">
- <a href={% project_url build.project %}>
- {{build.project.name}}
- </a>
- </span>
- {% endif %}
- <div class="row-fluid">
- <div class="span3 lead">
- {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
- <a href="{%url 'builddashboard' build.pk%}" class="{%if build.outcome == build.SUCCEEDED %}success{%else%}error{%endif%}">
- {% endif %}
- {% if build.target_set.all.count > 0 %}
- <span data-toggle="tooltip"
- {% if build.target_set.all.count > 1 %}
- {{build.get_sorted_target_list.0.target}}
- title="Recipes:
- {% for target in build.get_sorted_target_list %}
- {% if target.task %}
- {{target.target}}:{{target.task}}
- {% else %}
- {{target.target}}
- {% endif %}
- {% endfor %}"
- {% endif %}
- >
- {% if build.target_set.all.0.task %}
- {{build.get_sorted_target_list.0.target}}:{{build.target_set.all.0.task}}
- {% else %}
- {{build.get_sorted_target_list.0.target}}
- {% endif %}
- {% if build.target_set.all.count > 1 %}
- (+{{build.target_set.all.count|add:"-1"}})
- {% endif %}
- </span>
- {% endif %}
- {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
+ {% for build in mru %}
+ <div data-latest-build-result="{{build.id}}" class="alert build-result {% if build.outcome == build.SUCCEEDED %}alert-success{% elif build.outcome == build.FAILED %}alert-danger{% else %}alert-info{% endif %}">
+ <!-- project title -->
+ {% if mrb_type != 'project' %}
+ <div class="row project-name">
+ <div class="col-md-12">
+ <small>
+ <a class="alert-link text-uppercase" href="{% project_url build.project %}">
+ {{build.project.name}}
</a>
- {% endif %}
- </div>
- {% if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
- <div class="span2 lead">
- {% if build.completed_on|format_build_date %}
- {{ build.completed_on|date:'d/m/y H:i' }}
- {% else %}
- {{ build.completed_on|date:'H:i' }}
- {% endif %}
- </div>
- {% endif %}
- {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
- <div class="span2 lead">
- {% if build.errors.count %}
- <i class="icon-minus-sign red"></i> <a href="{%url 'builddashboard' build.pk%}#errors" class="error">{{build.errors.count}} error{{build.errors.count|pluralize}}</a>
- {% endif %}
- </div>
- <div class="span2 lead">
- {% if build.warnings.count %}
- <i class="icon-warning-sign yellow"></i> <a href="{%url 'builddashboard' build.pk%}#warnings" class="warning">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a>
- {% endif %}
- </div>
- <div class="lead ">
- <span class="lead">
- Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a>
- </span>
- {% if build.project.is_default %}
- <i class="pull-right icon-question-sign get-help
- {% if build.outcome == build.SUCCEEDED %}
- get-help-green
- {% elif build.outcome == build.FAILED %}
- get-help-red
- {% else %}
- get-help-blue
- {% endif %}
- " title="Builds in this project cannot be started from Toaster: they are started from the command line">
- </i>
- {% else %}
- <button class="run-again-btn btn
- {% if build.outcome == build.SUCCEEDED %}
- btn-success
- {% elif build.outcome == build.FAILED %}
- btn-danger
- {% else %}
- btn-info
- {%endif%}
- pull-right"
- data-request-url="{% url 'xhr_buildrequest' build.project.pk %}"
- data-target='{{build.target_set.all|get_tasks|json}}'>
-
-
- Rebuild
- </button>
- {% endif %}
+ </small>
</div>
- {%endif%}
- {%if build.outcome == build.IN_PROGRESS %}
- <div class="span4" style="display:none" id="cancelling-msg-{{build.buildrequest.pk}}">
- <p class="lead">Cancelling the build ...</p>
- </div>
- <div class="span4 offset1 progress-info">
- <div class="progress" id="build-pc-done-title-{{build.pk}}" style="margin-top:5px;" data-toggle="tooltip" title="{{build.completeper}}% of tasks complete">
- <div id="build-pc-done-bar-{{build.pk}}" style="width: {{build.completeper}}%;" class="bar"></div>
+ </div>
+ {% endif %}
+
+ <div class="row" data-role="build-status-container">
+ <div class="col-md-12">
+ Loading...
+ </div>
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+{% endif %}
+
+<!-- build main template -->
+<script id="build-template" type="text/x-jsrender">
+ <div class="col-md-3">
+ <!-- only show link for completed builds -->
+ <%if state == 'Succeeded' || state == 'Failed'%>
+ <a class="alert-link" href="<%:dashboard_url%>">
+ <span data-toggle="tooltip" data-role="targets-text" title="Recipes: <%:targets%>">
+ <%:targets_abbreviated%>
+ </span>
+ </a>
+ <%else targets_abbreviated !== ''%>
+ <span data-toggle="tooltip" data-role="targets-text" title="Recipes: <%:targets%>">
+ <%:targets_abbreviated%>
+ </span>
+ <%else%>
+ Fetching recipe names...
+ <%/if%>
+ </div>
+
+ <div data-build-state="<%:state%>">
+ <%if state == 'Parsing'%>
+ <%include tmpl='#parsing-recipes-build-template'/%>
+ <%else state == 'Queued'%>
+ <%include tmpl='#queued-build-template'/%>
+ <%else state == 'Succeeded' || state == 'Failed'%>
+ <%include tmpl='#succeeded-or-failed-build-template'/%>
+ <%else state == 'Cancelling'%>
+ <%include tmpl='#cancelling-build-template'/%>
+ <%else state == 'Starting'%>
+ <%include tmpl='#starting-template'/%>
+ <%else state == 'In Progress'%>
+ <%include tmpl='#in-progress-build-template'/%>
+ <%else state == 'Cancelled'%>
+ <%include tmpl='#cancelled-build-template'/%>
+ <%/if%>
+ </div>
+</script>
+
+<!-- queued build -->
+<script id="queued-build-template" type="text/x-jsrender">
+ <div class="col-md-5">
+ <span class="glyphicon glyphicon-question-sign get-help get-help-blue"
+ title="This build is waiting for the build directory to become available">
+ </span>
+
+ Build queued
+ </div>
+
+ <div class="col-md-4">
+ <!-- cancel button -->
+ <%include tmpl='#cancel-template'/%>
+ </div>
+</script>
+
+<!-- parsing recipes build -->
+<script id="parsing-recipes-build-template" type="text/x-jsrender">
+ <!-- progress bar and parse completion percentage -->
+ <div data-role="build-status" class="col-md-4 col-md-offset-1 progress-info">
+ <!-- progress bar -->
+ <div class="progress">
+ <div id="recipes-parsed-percentage-bar-<%:id%>"
+ style="width: <%:recipes_parsed_percentage%>%;"
+ class="progress-bar">
</div>
</div>
- <div class="lead span3 progress-info"><span id="build-pc-done-{{build.pk}}">{{build.completeper}}</span>% of tasks complete</div>
- {# No build cancel for command line builds project #}
- {% if build.project.is_default %}
- <i class="icon-question-sign get-help get-help-blue pull-right" title="" data-original-title="Builds in this project cannot be cancelled from Toaster: they can only be cancalled from the command line"></i>
- {% else %}
- <div class="lead pull-right progress-info">
- <button class="cancel-build-btn btn btn-info pull-right"
- data-buildrequest-id={{build.buildrequest.pk}}
- data-request-url="{% url 'xhr_buildrequest' build.project.pk %}" >
- Cancel
- </button>
- </div>
- {% endif %}
+ </div>
+
+ <div class="col-md-4 progress-info">
+ <!-- parse completion percentage -->
+ <span class="glyphicon glyphicon-question-sign get-help get-help-blue"
+ title="BitBake is parsing the layers required for your build">
+ </span>
+
+ Parsing <span id="recipes-parsed-percentage-<%:id%>"><%:recipes_parsed_percentage%></span>% complete
+
+ <%include tmpl='#cancel-template'/%>
+ </div>
+</script>
+
+<!-- in progress build; tasks still starting -->
+<script id="starting-template" type="text/x-jsrender">
+ <div class="col-md-5">
+ <span class="glyphicon glyphicon-question-sign get-help get-help-blue"
+ title="This build is waiting for tasks to start">
+ </span>
+
+ Tasks starting...
+ </div>
- {%endif%} {# end if in progress #}
+ <div class="col-md-4">
+ <!-- cancel button -->
+ <%include tmpl='#cancel-template'/%>
+ </div>
+</script>
- {% if build.outcome == build.CANCELLED %}
- <div class="span4">
- <p class="lead">Build cancelled</p>
+<!-- in progress build; at least one task finished -->
+<script id="in-progress-build-template" type="text/x-jsrender">
+ <!-- progress bar and task completion percentage -->
+ <div data-role="build-status" class="col-md-4 col-md-offset-1 progress-info">
+ <!-- progress bar -->
+ <div class="progress" id="build-pc-done-title-<%:id%>">
+ <div id="build-pc-done-bar-<%:id%>"
+ style="width: <%:tasks_complete_percentage%>%;"
+ class="progress-bar">
+ </div>
</div>
- <button class="btn btn-info pull-right run-again-btn"
- data-request-url="{% url 'xhr_buildrequest' build.project.pk %}"
- data-target='{{build.target_set.all|get_tasks|json}}'>
- Rebuild
+ </div>
+
+ <div class="col-md-4 progress-info">
+ <!-- task completion percentage -->
+ <span id="build-pc-done-<%:id%>"><%:tasks_complete_percentage%></span>% of
+ tasks complete
+
+ <!-- cancel button -->
+ <%include tmpl='#cancel-template'/%>
+ </div>
+</script>
+
+<!-- cancelling build -->
+<script id="cancelling-build-template" type="text/x-jsrender">
+ <div class="col-md-9">
+ Cancelling the build ...
+ </div>
+</script>
+
+<!-- succeeded or failed build -->
+<script id="succeeded-or-failed-build-template" type="text/x-jsrender">
+ <!-- completed_on -->
+ <div class="col-md-2">
+ <%:completed_on%>
+ </div>
+
+ <!-- errors -->
+ <div class="col-md-2">
+ <%if errors%>
+ <span class="glyphicon glyphicon-minus-sign"></span>
+ <a href="<%:dashboard_errors_url%>" class="alert-link">
+ <%:errors%> error<%:errors_pluralise%>
+ </a>
+ <%/if%>
+ </div>
+
+ <!-- warnings -->
+ <div class="col-md-2">
+ <%if warnings%>
+ <span class="glyphicon glyphicon-warning-sign build-warnings"></span>
+ <a href="<%:dashboard_warnings_url%>" class="alert-link build-warnings">
+ <%:warnings%> warning<%:warnings_pluralise%>
+ </a>
+ <%/if%>
+ </div>
+
+ <!-- build time -->
+ <div class="col-md-3">
+ Build time:
- </button>
- {% endif %}
+ <span data-role="data-recent-build-buildtime-field">
+ <%if state == 'Succeeded'%>
+ <a class="alert-link" href="<%:buildtime_url%>"><%:buildtime%></a>
+ <%else%>
+ <%:buildtime%>
+ <%/if%>
+ </span>
+
+ <!-- rebuild button -->
+ <%include tmpl='#rebuild-template'/%>
+ </div>
+</script>
+
+<!-- cancelled build -->
+<script id="cancelled-build-template" type="text/x-jsrender">
+ <!-- build cancelled message -->
+ <div class="col-md-6">
+ Build cancelled
</div>
-</div>
- {% endfor %}
+ <!-- rebuild button -->
+ <div class="col-md-3">
+ <%include tmpl='#rebuild-template'/%>
</div>
+</script>
+
+<!-- rebuild button or no rebuild icon -->
+<script id="rebuild-template" type="text/x-jsrender">
+ <%if is_default_project_build%>
+ <!-- no rebuild info icon -->
+ <span class="pull-right glyphicon glyphicon-question-sign get-help <%if state == 'Succeeded'%>get-help-green<%else state == 'Failed'%>get-help-red<%else%>get-help-blue<%/if%>"
+ title="Builds in this project cannot be started from Toaster: they are started from the command line">
+ </span>
+ <%else%>
+ <!-- rebuild button -->
+ <span class="rebuild-btn alert-link <%if state == 'Success'%>success<%else state == 'Failed'%>danger<%else%>info<%/if%> pull-right"
+ data-request-url="<%:rebuild_url%>" data-target='<%:build_targets_json%>'>
+ <span class="glyphicon glyphicon-repeat"></span>
+ Rebuild
+ </span>
+ <%/if%>
+</script>
-{%endif%}
+<!-- cancel button or no cancel icon -->
+<script id="cancel-template" type="text/x-jsrender">
+ <%if is_default_project_build%>
+ <!-- no cancel icon -->
+ <span class="glyphicon glyphicon-question-sign get-help get-help-blue pull-right" title="Builds in this project cannot be cancelled from Toaster: they can only be cancelled from the command line"></span>
+ <%else%>
+ <!-- cancel button -->
+ <span class="cancel-build-btn pull-right alert-link"
+ data-buildrequest-id="<%:buildrequest_id%>" data-request-url="<%:cancel_url%>">
+ <span class="glyphicon glyphicon-remove-circle"></span>
+ Cancel
+ </span>
+ <%/if%>
+</script>
+<script>
+ $(document).ready(function () {
+ var ctx = {
+ mrbType : "{{mrb_type}}",
+ }
+
+ try {
+ mrbSectionInit(ctx);
+ } catch (e) {
+ document.write("Sorry, An error has occurred loading this page");
+ console.warn(e);
+ }
+ });
+</script>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage.html
index 46aed901f..980179a40 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage.html
@@ -5,10 +5,17 @@
{% block pagecontent %}
{% include "newcustomimage_modal.html" %}
-{% include "projecttopbar.html" %}
-{% url table_name project.id as xhr_table_url %}
-<h2>{{title}} (<span class="table-count-{{table_name}}">0</span>)</h2>
-{% include "toastertable.html" %}
+<div class="row">
+
+ {% include "projecttopbar.html" %}
+
+ <div class="col-md-12">
+ {% url table_name project.id as xhr_table_url %}
+ <h2>{{title}} (<span class="table-count-{{table_name}}">0</span>)</h2>
+ {% include "toastertable.html" %}
+ </div>
+
+</div>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
index caeb30235..d448d3afc 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newcustomimage_modal.html
@@ -12,37 +12,49 @@
});
</script>
-<div class="modal hide fade in" id="new-custom-image-modal" aria-hidden="false">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">Ă—</button>
- <h3>New custom image</h3>
- </div>
+<div class="modal fade" id="new-custom-image-modal" aria-hidden="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">Ă—</button>
+ <h3>New custom image</h3>
+ </div>
- <div class="modal-body">
- <!--
- this container is visible if there are multiple image recipes which could
- be used as a basis for the new custom image; radio buttons are added to it
- via newCustomImageModalSetRecipes() as required
- -->
- <div data-role="image-selector" style="display:none;">
- <h4>Which image do you want to customise?</h4>
- <div data-role="image-selector-radios"></div>
- <span class="help-block error" id="invalid-recipe-help" style="display:none"></span>
- <div class="air"></div>
- </div>
+ <div class="modal-body">
+ <!--
+ this container is visible if there are multiple image recipes which could
+ be used as a basis for the new custom image; radio buttons are added to it
+ via newCustomImageModalSetRecipes() as required
+ -->
+ <div data-role="image-selector" style="display:none;">
+ <h4>Which image do you want to customise?</h4>
+ <span class="help-block text-danger" id="invalid-recipe-help" style="display:none"></span>
+ <div data-role="image-selector-radios"></div>
+ <div class="air"></div>
+ </div>
- <h4>Name your custom image</h4>
+ <h4>Name your custom image</h4>
- <div class="row-fluid">
- <span class="help-block span8">Image names must be unique. They should not contain spaces or capital letters, and the only allowed special character is dash (-).<p></p>
- </span></div>
- <div class="control-group controls">
- <input type="text" class="huge" placeholder="Type the custom image name" required>
- <span class="help-block error" id="invalid-name-help" style="display:none"></span>
- </div>
- </div>
+ <div class="row">
+ <div class="col-md-10">
+ <p class="help-block">Image names must be unique. They should not contain spaces or capital letters, and the only allowed special character is dash (-).
+ </p>
+ <div class="form-group">
+ <input type="text" class="form-control input-lg" placeholder="Type the custom image name" required>
+ </div>
+ <span class="help-block text-danger" id="invalid-name-help" style="display:none"></span>
+ </div>
+ </div>
+ </div>
- <div class="modal-footer">
- <button id="create-new-custom-image-btn" class="btn btn-primary btn-large" data-original-title="" title="" disabled>Create custom image</button>
+ <div class="modal-footer">
+ <button id="create-new-custom-image-btn" class="btn btn-primary btn-large" disabled>
+ <span data-role="submit-state">Create custom image</span>
+ <span data-role="loading-state" style="display:none">
+ <i class="fa-pulse icon-spinner"></i>&nbsp;Creating custom image...
+ </span>
+ </button>
+ </div>
+ </div>
</div>
</div>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newproject.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newproject.html
index e83b2bea6..acb614e9d 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newproject.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/newproject.html
@@ -5,24 +5,21 @@
{% block title %} Create a new project - Toaster {% endblock %}
{% block pagecontent %}
-<div class="row-fluid">
+<div class="row">
+ <div class="col-md-12">
<div class="page-header">
<h1>Create a new project</h1>
</div>
- <div class="container-fluid">
{% if alert %}
- <div class="alert alert-error row-fluid" role="alert">{{alert}}</div>
+ <div class="alert alert-danger" role="alert">{{alert}}</div>
{% endif %}
- </div>
- <div class="row-fluid">
- <div class="span6">
<form method="POST">{% csrf_token %}
-
- <fieldset>
- <label>Project name <span class="muted">(required)</span></label>
- <input type="text" class="input-xlarge" required id="new-project-name" name="projectname">
- </fieldset>
+ <div class="form-group" id="validate-project-name">
+ <label class="control-label">Project name <span class="text-muted">(required)</span></label>
+ <input type="text" class="form-control" required id="new-project-name" name="projectname">
+ </div>
+ <p class="help-block text-danger" style="display: none;" id="hint-error-project-name">A project with this name exists. Project names must be unique.</p>
<!--
<fieldset>
<label class="project-form">Project type</label>
@@ -35,13 +32,13 @@
<input type="hidden" name="ptype" value="build" />
{% if releases.count > 0 %}
- <fieldset class="release">
+ <div class="release form-group">
{% if releases.count > 1 %}
- <label class="project-form">
+ <label class="control-label">
Release
- <i class="icon-question-sign get-help" title="The version of the build system you want to use"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The version of the build system you want to use"></span>
</label>
- <select name="projectversion" id="projectversion">
+ <select name="projectversion" id="projectversion" class="form-control">
{% for release in releases %}
<option value="{{release.id}}"
{%if defaultbranch == release.name %}
@@ -50,25 +47,28 @@
>{{release.description}}</option>
{% endfor %}
</select>
+ <div class="row">
+ <div class="col-md-4">
{% for release in releases %}
- <div class="row-fluid helptext" id="description-{{release.id}}" style="display: none">
- <span class="help-block span5">{{release.helptext|safe}}</span>
- </div>
+ <div class="helptext" id="description-{{release.id}}" style="display: none">
+ <span class="help-block">{{release.helptext|safe}}</span>
+ </div>
{% endfor %}
{% else %}
<input type="hidden" name="projectversion" value="{{releases.0.id}}"/>
{% endif %}
+ </div>
+ </div>
</fieldset>
{% endif %}
-
- <div class="form-actions">
- <input type="submit" id="create-project-button" class="btn btn-primary btn-large" value="Create project"/>
+ <div class="top-air">
+ <input type="submit" id="create-project-button" class="btn btn-primary btn-lg" value="Create project"/>
<span class="help-inline" style="vertical-align:middle;">To create a project, you need to enter a project name</span>
</div>
+
</form>
- </div>
<!--
- <div class="span5 well">
+ <div class="col-md-5 well">
<span class="help-block">
<h4>Toaster project types</h4>
<p>With a <strong>build project</strong> you configure and run your builds from Toaster.</p>
@@ -81,7 +81,7 @@
<p>If you create a <strong>build project</strong>, you will need to select a <strong>release</strong>,
which is the version of the build system you want to use to run your builds.</p>
</div> -->
- </div>
+ </div>
</div>
<script type="text/javascript">
@@ -113,6 +113,11 @@
$('#description-' + new_release).fadeIn();
});
+ libtoaster.makeProjectNameValidation($("#new-project-name"),
+ $("#hint-error-project-name"), $("#validate-project-name"),
+ $(".btn-primary"));
+
+
/* // Hide the project release when you select an analysis project
function projectType() {
if ($("input[type='radio']:checked").val() == 'build') {
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html
index e6f20c330..a5d589357 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html
@@ -2,16 +2,16 @@
{% load projecttags %}
{% block tabcontent %}
- <ul class="nav nav-pills">
+ <ul class="nav nav-tabs">
<li class="">
<a href="{% url 'package_built_detail' build.id package.id %}">
- <i class="icon-question-sign get-help" title="Shows the files produced by this package."></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Shows the files produced by this package."></span>
Generated files ({{package.buildfilelist_package.count}})
</a>
</li>
<li class="active">
<a href="{% url 'package_built_dependencies' build.id package.id %}">
- <i class="icon-question-sign get-help" title="Shows the runtime packages required by this package."></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Shows the runtime packages required by this package."></span>
Runtime dependencies ({{dependency_count}})
</a>
</li>
@@ -24,14 +24,14 @@
</div>
{% else %}
<div class="alert alert-info">
- <strong>{{package.fullpackagespec}}</strong> is <strong>not included</strong> in any image. This page shows you the projected runtime dependencies if you include <strong>{{package.fullpackagespec}}</strong> in future builds.
+ <strong>{{package.fullpackagespec}}</strong> is <strong>not included</strong> in any image. This page shows you the projected runtime dependencies if you were to include <strong>{{package.fullpackagespec}}</strong> in an image.
</div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Package</th>
<th>Version</th>
- <th class="sizecol span2">Size</th>
+ <th class="sizecol col-md-2">Size</th>
</tr>
</thead>
<tbody>
@@ -62,9 +62,9 @@
<tr>
<th>Package</th>
<th>Version</th>
- <th class="sizecol span2">Size</th>
+ <th class="sizecol col-md-2">Size</th>
<th>
- <i class="icon-question-sign get-help" title="Five relationship types exist: recommends, suggests, provides, replaces and conflicts"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Five relationship types exist: recommends, suggests, provides, replaces and conflicts"></span>
Relationship type
</th>
</tr>
@@ -87,7 +87,7 @@
<td class="sizecol">{{other_dep.size|filtered_filesizeformat}}</td>
<td>
{{other_dep.dep_type_display}}
- <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i>
+ <span class="glyphicon glyphicon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></span>
</td>
</tr>
{% endfor %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_detail.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_detail.html
index 9be8ccb85..0bdbc2a41 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_detail.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_built_detail.html
@@ -6,13 +6,13 @@
<!-- Generated Files -->
{% if package.buildtargetlist_package.count == 0 %}
{# Not included case #}
- <ul class="nav nav-pills">
+ <ul class="nav nav-tabs">
<li class="active"> <a href="#">
- <i class="icon-question-sign get-help" title="Files added to a root file system when you include {{package.name}} in an image"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Files added to a root file system when you include {{package.name}} in an image"></span>
Generated files ({{packageFileCount}})
</a></li>
<li class=""><a href="{% url 'package_built_dependencies' build.id package.id %}">
- <i class="icon-question-sign get-help" title="Projected runtime dependencies when you include {{package.name}} in an image"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Projected runtime dependencies when you include {{package.name}} in an image"></span>
Runtime dependencies ({{dependency_count}})
</a></li>
</ul>
@@ -21,7 +21,7 @@
<!-- Package file list or if empty, alert pane -->
{% if packageFileCount > 0 %}
<div class="alert alert-info">
- <strong>{{package.fullpackagespec}}</strong> is <strong>not included</strong> in any image. This page shows you the files added to an image root file system if you include <strong>{{package.fullpackagespec}}</strong> in future builds.
+ <strong>{{package.fullpackagespec}}</strong> is <strong>not included</strong> in any image. This page shows you the files that would be added to an image root file system with <strong>{{package.fullpackagespec}}</strong> included in it.
</div>
{% include "tablesort.html" %}
<tbody>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_detail_base.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
index 9fa28a8f8..66f8e7f06 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_detail_base.html
@@ -14,8 +14,8 @@
function fmtAliasHelp(package_name, alias, hover) {
var r = null;
if (alias != null && alias != '') {
- r = '<span class="muted"> as ' + alias + '&nbsp';
- r += '<i class="icon-question-sign get-help';
+ r = '<span class="text-muted"> as ' + alias + '&nbsp';
+ r += '<span class="glyphicon glyphicon-question-sign get-help';
if (hover) {
r+= ' hover-help';
}
@@ -23,9 +23,9 @@
r+= ' heading-help';
}
r += '"';
- title = package_name + ' was renamed at packaging time and was installed on your system as ' + alias;
+ title = '<code>' + package_name + '</code> was renamed at packaging time and was installed on your system as <code>' + alias + '</code>';
r += ' title="' + title + '">';
- r += '</i>';
+ r += '</span>';
r += '</span>';
document.write(r);
}
@@ -43,28 +43,32 @@
{% endblock localbreadcrumb %}
{% block pagedetailinfomain %}
- <div class="row span11">
- <div class="page-header">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="page-header build-data">
{% block mainheading %}
<h1>{{package.fullpackagespec}}</h1>
{% endblock %}
</div> <!-- page-header -->
- </div> <!-- row span11 page-header -->
+ </div> <!-- col-md-12 page-header -->
+ </div> <!-- end row -->
{% block twocolumns %}
- <div class="row span7 tabbable">
+ <div class="row">
+ <div class="col-md-8 tabbable">
{% block tabcontent %}
{% endblock tabcontent %}
- </div> <!-- row span7 -->
+ </div> <!-- row col-md-8 -->
- <div class="row span4 well">
+ <div class="col-md-4">
+ <div class="well">
<h2>Package information</h2>
<!-- info presented as definition list -->
<dl class="item-info">
<dt>
Size
- <i class="icon-question-sign get-help" title="The size of the package"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The size of the package"></span>
</dt>
<dd>
{% comment %}
@@ -81,7 +85,7 @@
<dt>
License
- <i class="icon-question-sign get-help" title="The license under which this package is distributed"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The license under which this package is distributed"></span>
</dt>
<dd>{{package.license}}</dd>
@@ -97,7 +101,7 @@
<dt>
Recipe
- <i class="icon-question-sign get-help" title="The name of the recipe building this package"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The name of the recipe building this package"></span>
</dt>
<dd>
{% if package.recipe_id > 0 %}
@@ -109,13 +113,13 @@
<dt>
Recipe version
- <i class="icon-question-sign get-help" title="The version of the recipe building this package"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The version of the recipe building this package"></span>
</dt>
<dd>{{package.recipe.version}}</dd>
<dt>
Layer
- <i class="icon-question-sign get-help" title="The name of the layer providing the recipe that builds this package"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The name of the layer providing the recipe that builds this package"></span>
</dt>
<dd>
{{package.recipe.layer_version.layer.name}}
@@ -124,26 +128,42 @@
# Removed per team meeting of 1/29/2014 until
# decision on index search algorithm
<a href="http://layers.openembedded.org" target="_blank">
- <i class="icon-share get-info"></i>
+ <i class="glyphicon glyphicon-share get-info"></i>
</a>
{% endcomment %}
{% endif %}
</dd>
- {% if package.recipe.layer_version.branch %}
<dt>
Layer branch
- <i class="icon-question-sign get-help" title="The Git branch of the layer providing the recipe that builds this package"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The Git branch of the layer providing the recipe that builds this package"></span>
+ {%if package.recipe.layer_version.layer.local_source_dir %}
+ <dd>
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The source code of {{package.recipe.layer_version.layer.name}} is not in a Git repository, so there is no branch associated with it"></span>
+ </dd>
+ {% endif %}
</dt>
+ {% if not package.recipe.layer_version.layer.local_source_dir %}
<dd>{{package.recipe.layer_version.branch}}</dd>
- {% endif %}
+ {% endif %}
<dt>
Layer commit
- <i class="icon-question-sign get-help" title="The Git commit of the layer providing the recipe that builds this package"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The Git commit of the layer providing the recipe that builds this package"></span>
+ {%if package.recipe.layer_version.layer.local_source_dir %}
+ <dd>
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The source code of {{package.recipe.layer_version.layer.name}} is not in a Git repository, so there is no commit associated with it"></span>
+ </dd>
+ {% endif %}
</dt>
+ {% if not package.recipe.layer_version.layer.local_source_dir %}
<dd class="iscommit">{{package.recipe.layer_version.commit}}</dd>
+ {% endif %}
</dl>
- </div> <!-- row4 well -->
+ <div> <!-- end well -->
+ </div> <!-- end 4-column section -->
{% endblock twocolumns %}
+ </div> <!-- end row -->
{% endblock pagedetailinfomain %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html
index 8a0508e70..95e56ded2 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html
@@ -20,11 +20,11 @@
<tr>
<th>Package</th>
<th>Version</th>
- <th class='sizecol span2'>Size</th>
+ <th class='sizecol col-md-2'>Size</th>
</tr>
</thead>
<tbody>
- {% for runtime_dep in runtime_deps %}
+ {% for runtime_dep in runtime_deps %}
<tr {{runtime_dep.size|format_vpackage_rowclass}} >
{% if runtime_dep.size != -1 %}
<td>
@@ -41,7 +41,7 @@
<td>{{runtime_dep.version}}&nbsp;</td>
<td class='sizecol'>{{runtime_dep.size|filtered_filesizeformat}}&nbsp;</td>
</tr>
- {% endfor %}
+ {% endfor %}
</tbody>
</table>
{% else %}
@@ -57,15 +57,15 @@
<tr>
<th>Package</th>
<th>Version</th>
- <th class='sizecol span2'>Size</th>
+ <th class='sizecol col-md-2'>Size</th>
<th>
- <i class="icon-question-sign get-help" title="Five relationship types exist: recommends, suggests, provides, replaces and conflicts"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Five relationship types exist: recommends, suggests, provides, replaces and conflicts"></span>
Relationship type
</th>
</tr>
</thead>
<tbody>
- {% for other_dep in other_deps %}
+ {% for other_dep in other_deps %}
{% if other_dep.installed %}
<tr {{other_dep.size|format_vpackage_rowclass}}>
{% if other_dep.size != -1 %}
@@ -86,21 +86,21 @@
<td class='sizecol'>{{other_dep.size|filtered_filesizeformat}}&nbsp;</td>
<td>
{{other_dep.dep_type_display}}
- <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i>
+ <span class="glyphicon glyphicon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></span>
</td>
</tr>
{% else %}
- <tr class="muted">
+ <tr class="text-muted">
<td>{{other_dep.name}}</td>
<td>{{other_dep.version}}</td>
<td></td>
<td>
{{other_dep.dep_type_display}}
- <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i>
+ <span class="glyphicon glyphicon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></span>
</td>
</tr>
{% endif %}
- {% endfor %}
+ {% endfor %}
</tbody>
</table>
{% endifnotequal %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html
index 958aa8827..e89fa211c 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html
@@ -1,12 +1,12 @@
- <ul class="nav nav-pills">
+ <ul class="nav nav-tabs">
{% if active_tab == "detail" %}
<li class="active">
{% else %}
<li class="">
{% endif %}
<a href="{% url 'package_included_detail' build.id target.id package.id %}">
- <i class="icon-question-sign get-help" title="The files this package adds to the image root file system"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The files this package adds to the image root file system"></span>
Files in root file system ({{packageFileCount}})
</a>
</li>
@@ -16,7 +16,7 @@
<li class="">
{% endif %}
<a href="{% url 'package_included_dependencies' build.id target.id package.id %}">
- <i class="icon-question-sign get-help" title="Package runtime dependencies"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Package runtime dependencies"></span>
Runtime dependencies ({{dependency_count}})
</a>
</li>
@@ -26,7 +26,7 @@
<li class="">
{% endif %}
<a href="{% url 'package_included_reverse_dependencies' build.id target.id package.id %}">
- <i class="icon-question-sign get-help" title="The package runtime reverse dependencies (i.e. the packages in this image that depend on this package). Reverse dependencies reflect only the 'depends' dependency type"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The package runtime reverse dependencies (i.e. the packages in this image that depend on this package). Reverse dependencies reflect only the 'depends' dependency type"></span>
Reverse runtime dependencies ({{reverse_count}})
</a>
</li>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html
index 0aefc5625..303faecbd 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html
@@ -1,12 +1,12 @@
{# TODO move to snippets dir #}
{% if data.is_locale_package %}
<p class="text-center">
- <span class="muted">Locale package</span>
- <i class="icon-question-sign get-help hover-help" title=""
- data-original-title="This package is included in your image
+ <span class="text-muted">Locale package</span>
+ <span class="glyphicon glyphicon-question-sign get-help hover-help"
+ title="This package is included in your image
based on the locale specified in the IMAGE_LINGUAS variable"
style="visibility: hidden;">
- </i>
+ </span>
</p>
{% else %}
@@ -21,12 +21,12 @@
<i class="icon-trash no-tooltip"></i>
Remove package
</button>
- <button class="btn btn-block add-rm-package-btn" data-directive="add" data-id="{{data.pk}}" data-package-url="{% url 'xhr_customrecipe_packages' extra.recipe_id data.pk %}" data-name="{{data.name}}" style="
+ <button class="btn btn-default btn-block add-rm-package-btn" data-directive="add" data-id="{{data.pk}}" data-package-url="{% url 'xhr_customrecipe_packages' extra.recipe_id data.pk %}" data-name="{{data.name}}" style="
{% if data.pk in extra.current_packages %}
display:none
{% endif %}
">
- <i class="icon-plus"></i>
+ <i class="glyphicon glyphicon-plus"></i>
Add package
</button>
</div>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/project.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/project.html
index 125676881..5abe24130 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/project.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/project.html
@@ -24,44 +24,55 @@
});
</script>
-<!-- Comment out the ability to change the project release, until we decide what to do this functionality -->
-
-<!--div id="change-release-modal" class="modal hide fade in" tabindex="-1" role="dialog" aria-labelledby="change-release-modal" aria-hidden="false">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
- <h3>Changing Yocto Project release to <span class="proposed-release-change-name"></span></h3>
- </div>
- <div class="modal-body">
- <p>The following added layers do not exist for <span class="proposed-release-change-name"></span>: </p>
- <ul id="layers-to-remove-list">
- </ul>
- <p>If you change the Yocto Project release to <span class="proposed-release-change-name"></span>, the above layers will be deleted from your added layers.</p>
- </div>
- <div class="modal-footer">
- <button id="change-release-and-rm-layers" data-dismiss="modal" type="submit" class="btn btn-primary">Change release and delete layers</button>
- <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
- </div>
-</div-->
+<div id="delete-project-modal" class="modal fade" tabindex="-1" role="dialog" data-backdrop="static" data-keyboard="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h4>Are you sure you want to delete this project?</h4>
+ </div>
+ <div class="modal-body">
+ <p>Deleting the <strong class="project-name"></strong> project
+ will:</p>
+ <ul>
+ <li>Cancel its builds currently in progress</li>
+ <li>Remove its configuration information</li>
+ <li>Remove its imported layers</li>
+ <li>Remove its custom images</li>
+ <li>Remove all its build information</li>
+ </ul>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-primary" id="delete-project-confirmed">
+ <span data-role="submit-state">Delete project</span>
+ <span data-role="loading-state" style="display:none">
+ <span class="fa-pulse">
+ <i class="fa-pulse icon-spinner"></i>
+ </span>
+ &nbsp;Deleting project...
+ </span>
+ </button>
+ <button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button>
+ </div>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div>
-<div class="row-fluid" id="project-page" style="display:none">
- <div class="span6">
+<div class="row" id="project-page" style="display:none">
+ <div class="col-md-6">
<div class="well well-transparent" id="machine-section">
<h3>Machine</h3>
- <p class="lead"><span id="project-machine-name"></span> <i title="" data-original-title="" id="change-machine-toggle" class="icon-pencil"></i></p>
-
- <form id="select-machine-form" style="display:none;">
- <div class="alert alert-info">
- <strong>Machine changes have a big impact on build outcome.</strong> You cannot really compare the builds for the new machine with the previous ones.
- </div>
+ <p class="lead"><span id="project-machine-name"></span> <span class="glyphicon glyphicon-edit" id="change-machine-toggle"></span></p>
- <div class="input-append">
- <input id="machine-change-input" autocomplete="off" value="" data-provide="typeahead" data-minlength="1" data-autocomplete="off" type="text">
- <button id="machine-change-btn" class="btn" type="button">Save</button> <a href="#" id="cancel-machine-change" class="btn btn-link">Cancel</a>
+ <form id="select-machine-form" style="display:none;" class="form-inline">
+ <span class="help-block">Machine suggestions come from the list of layers added to your project. If you don't see the machine you are looking for, <a href="{% url 'projectmachines' project.id %}">check the full list of machines</a></span>
+ <div class="form-group">
+ <input class="form-control" id="machine-change-input" autocomplete="off" value="" data-provide="typeahead" data-minlength="1" data-autocomplete="off" type="text">
</div>
-
- <p><a href="{% url 'projectmachines' project.id %}" class="link">View compatible machines</a></p>
+ <button id="machine-change-btn" class="btn btn-default" type="button">Save</button>
+ <a href="#" id="cancel-machine-change" class="btn btn-link">Cancel</a>
+ <p class="form-link"><a href="{% url 'projectmachines' project.id %}">View compatible machines</a></p>
</form>
</div>
@@ -69,11 +80,11 @@
<h3>Most built recipes</h3>
<div class="alert alert-info" style="display:none" id="no-most-built">
- <span class="lead">You haven't built any recipes yet</span>
- <p style="margin-top: 10px;"><a href="{% url 'projectimagerecipes' project.id %}">Choose a recipe to build</a></p>
+ <h4>You haven't built any recipes yet</h4>
+ <p class="form-link"><a href="{% url 'projectimagerecipes' project.id %}">Choose a recipe to build</a></p>
</div>
- <ul class="unstyled configuration-list" id="freq-build-list">
+ <ul class="list-unstyled lead" id="freq-build-list">
</ul>
<button class="btn btn-primary" id="freq-build-btn" disabled="disabled">Build selected recipes</button>
</div>
@@ -97,44 +108,37 @@
</div>
</div>
- <div class="span6">
+ <div class="col-md-6">
<div class="well well-transparent" id="layer-container">
- <h3>Layers <span class="muted counter">(<span id="project-layers-count"></span>)</span>
- <i data-original-title="OpenEmbedded organises metadata into modules called 'layers'. Layers allow you to isolate different types of customizations from each other. <a href='http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#understanding-and-creating-layers' target='_blank'>More on layers</a>" class="icon-question-sign get-help heading-help" title=""></i>
+ <h3>Layers <span class="counter">(<span id="project-layers-count"></span>)</span>
+ <span title="OpenEmbedded organises recipes and machines into thematic groups called <strong>layers</strong>. Click on a layer name to see the recipes and machines it includes." class="glyphicon glyphicon-question-sign get-help"></span>
</h3>
- <div class="alert lead" id="no-layers-in-project" style="display:none">
- You need to add some layers. For that you can:
+ <div class="alert alert-warning" id="no-layers-in-project" style="display:none">
+ <h4>This project has no layers</h4>
+ In order to build this project you need to add some layers first. For that you can:
<ul>
- <li><a href="{% url 'projectlayers' project.id %}">View all layers compatible with this project</a></li>
+ <li><a href="{% url 'projectlayers' project.id %}">Choose from the layers compatible with this project</a></li>
<li><a href="{% url 'importlayer' project.id %}">Import a layer</a></li>
<li><a href="http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#understanding-and-creating-layers" target="_blank">Read about layers in the documentation</a></li>
+ <li>Or type a layer name below</li>
</ul>
- <p>Or type a layer name below.</p>
</div>
- <form style="margin-top:20px">
- <!--div class="control-group error"-->
-
- <div class="input-append">
- <input id="layer-add-input" autocomplete="off" placeholder="Type a layer name" data-minlength="1" data-autocomplete="off" data-provide="typeahead" data-source="" type="text">
- <button id="add-layer-btn" class="btn" disabled>Add</button>
+ <form class="form-inline">
+ <div class="form-group">
+ <input id="layer-add-input" class="form-control" autocomplete="off" placeholder="Type a layer name" data-minlength="1" data-autocomplete="off" data-provide="typeahead" data-source="" type="text">
</div>
-
- <div id="import-alert" class="alert alert-info" style="display:none;">
- Toaster does not know about this layer. Please <a href="#">import it</a>
- </div>
-
- <p>
+ <button id="add-layer-btn" class="btn btn-default" disabled>Add layer</button>
+ <p class="form-link">
<a href="{% url 'projectlayers' project.id %}" id="view-compatible-layers">View compatible layers</a>
- <i data-original-title="View all the layers you can build with the release selected for this project, which is Yocto Project master" class="icon-question-sign get-help" title=""></i>
- | <a href="{% url 'importlayer' project.id %}">Import layer</a>
+ <span class="text-muted">|</span>
+ <a href="{% url 'importlayer' project.id %}">Import layer</a>
</p>
</form>
- <ul class="unstyled configuration-list" id="layers-in-project-list">
+ <ul class="list-unstyled lead" id="layers-in-project-list">
</ul>
- </div>
</div>
</div>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html
index 6d7e10bac..a5fed2dd4 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds-toastertable.html
@@ -3,54 +3,63 @@
{% load static %}
{% block extraheadcontent %}
- <link rel="stylesheet" href="{% static 'css/jquery-ui.min.css' %}" type='text/css'>
- <link rel="stylesheet" href="{% static 'css/jquery-ui.structure.min.css' %}" type='text/css'>
- <link rel="stylesheet" href="{% static 'css/jquery-ui.theme.min.css' %}" type='text/css'>
- <script src="{% static 'js/jquery-ui.min.js' %}">
- </script>
+<link rel="stylesheet" href="{% static 'css/jquery-ui.min.css' %}" type='text/css'>
+<link rel="stylesheet" href="{% static 'css/jquery-ui.structure.min.css' %}" type='text/css'>
+<link rel="stylesheet" href="{% static 'css/jquery-ui.theme.min.css' %}" type='text/css'>
+<script src="{% static 'js/jquery-ui.min.js' %}">
+</script>
{% endblock %}
{% block title %} {{title}} - {{project.name}} - Toaster {% endblock %}
{% block pagecontent %}
+<div class="row">
{% include "projecttopbar.html" %}
- <div class="row-fluid">
+ <div class="col-md-12">
{% with mru=mru mrb_type=mrb_type %}
- {% include 'mrb_section.html' %}
+ {% include 'mrb_section.html' %}
{% endwith %}
- <h2 class="page-header top-air" data-role="page-title"></h2>
+ <h2 class="top-air" data-role="page-title"></h2>
+ {% if not build_in_progress_none_completed %}
{% url 'projectbuilds' project.id as xhr_table_url %}
{% include 'toastertable.html' %}
+ {% endif %}
</div>
- <script>
- $(document).ready(function () {
- // title
- var tableElt = $("#{{table_name}}");
- var titleElt = $("[data-role='page-title']");
+ <script>
+ $(document).ready(function () {
+ // title
+ var tableElt = $("#{{table_name}}");
+ var titleElt = $("[data-role='page-title']");
- tableElt.on("table-done", function (e, total, tableParams) {
- var title = "All project builds";
+ tableElt.on("table-done", function (e, total, tableParams) {
+ var title = "All project builds";
- if (tableParams.search || tableParams.filter) {
- if (total === 0) {
- title = "No project builds found";
- }
- else if (total > 0) {
- title = total + " project build" + (total > 1 ? 's' : '') + " found";
- }
- }
+ if (tableParams.search || tableParams.filter) {
+ if (total === 0) {
+ title = "No project builds found";
+ }
+ else if (total > 0) {
+ title = total + " project build" + (total > 1 ? 's' : '') + " found";
+ }
+ }
- titleElt.text(title);
- });
+ if (total === 0) {
+ titleElt.hide();
+ } else {
+ titleElt.show();
+ titleElt.text(title);
+ }
+ });
- // highlight builds tab
- $("#topbar-builds-tab").addClass("active")
- });
- </script>
+ // highlight builds tab
+ $("#topbar-builds-tab").addClass("active")
+ });
+ </script>
+</div>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds.html
index 3402fc4fe..50697a159 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectbuilds.html
@@ -39,10 +39,10 @@
{% if objects.paginator.count == 0 %}
{% if request.GET.filter or request.GET.search %}
- <div class="row-fluid">
+ <div class="row">
<div class="alert">
<form class="no-results input-append" id="searchform">
- <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
+ <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="input-append-addon btn" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></a>{% endif %}
<button class="btn" type="submit" value="Search">Search</button>
<button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all builds</button>
</form>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectconf.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectconf.html
index 27a898b65..fcf6df2bf 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectconf.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projectconf.html
@@ -6,945 +6,1034 @@
{% block projectinfomain %}
<h2>Bitbake variables</h2>
-
- <div style="padding-left:19px;">
-
- <dl class="dl-vertical">
- {% if distro_defined %}
- <dt>
- <span class="js-config-var-name js-config-var-managed-name">DISTRO</span>
- <i class="icon-question-sign get-help" title="The short name of the distribution. If the variable is blank, meta/conf/distro/defaultsetup.conf will be used. <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-DISTRO' target='_blank'>Read more in the manual</a>"></i>
- </dt>
- <dd class="lead">
- <span id="distro">{{distro}}</span>
- <i class="icon-pencil" id="change-distro-icon"></i>
- <form id="change-distro-form" style="display:none;">
- <div class="input-append">
- <span id="edit-distro-name-div" class="control-group">
- <input type="text" id="new-distro" value="{{distro}}">
- <button id="apply-change-distro" class="btn" type="button">Save</button>
- <button id="cancel-change-distro" type="button" class="btn btn-link">Cancel</button>
- </span>
- <span class="help-block error" id="distro-error-message"></span>
- </div>
- </form>
- </dd>
- {% endif %}
-
- {% if dl_dir_defined %}
- <dt>
- <span class="js-config-var-name js-config-var-managed-name">DL_DIR</span>
- <i class="icon-question-sign get-help" title="Absolute path to the directory used to store downloads required for your builds. By default, Toaster projects share the same downloads directory.<br /><a href='http://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#var-DL_DIR' target='_blank'>Read more in the manual</a>"></i>
- </dt>
- <dd class="lead">
- <span id="dl_dir"{% if dl_dir %}{%else%} class="muted"{%endif%}>{% if dl_dir %}{{dl_dir}}{%else%}Not set{%endif%}</span>
- <i class="icon-pencil" id="change-dl_dir-icon"></i>
- <form id="change-dl_dir-form" style="display:none;">
- <div class="row-fluid">
- <span class="help-block span4">To set DL_DIR type the absolute path of the download folder.</span>
- </div>
- <div class="input-append" id="validate-dl_dir">
- <input type="text" class="input-xlarge" id="new-dl_dir" placeholder="Type absolute path of the DL_DIR folder">
- <button id="apply-change-dl_dir" class="btn" type="button">Save</button>
- <button id="cancel-change-dl_dir" type="button" class="btn btn-link">Cancel</button>
- </br><span class="help-block error" id="hintError-dl_dir">A valid directory cannot include spaces or any of these characters: . \ ? % * : | " " < ></span>
- </div>
- </form>
- </dd>
- {% endif %}
-
- {% if fstypes_defined %}
- <dt>
- <span class="js-config-var-name js-config-var-managed-name">IMAGE_FSTYPES</span>
- <i class="icon-question-sign get-help" title="Formats of root file system images that you want to have created <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-IMAGE_FSTYPES' target='_blank'>Read more in the manual</a>"></i>
- </dt>
- <dd class="lead">
- <span id="image_fstypes">{{fstypes}}</span>
- <i class="icon-pencil" id="change-image_fstypes-icon"></i>
- <form id="change-image_fstypes-form" style="display:none;">
- <input id="filter-image_fstypes" type="text" placeholder="Search image types" class="span4">
- <div id="all-image_fstypes" class="scrolling">
- </div>
- <span class="help-block" id="fstypes-error-message">You must select at least one image type</span>
- <button id="apply-change-image_fstypes" type="button" class="btn">Save</button>
- <button id="cancel-change-image_fstypes" type="button" class="btn btn-link">Cancel</button>
- </form>
- </dd>
- {% endif %}
-
- {% if image_install_append_defined %}
- <dt>
- <span class="js-config-var-name js-config-var-managed-name">IMAGE_INSTALL_append</span>
- <i class="icon-question-sign get-help" title="Specifies additional packages to install into an image. If your build creates more than one image, the packages will be installed in <strong>all of them</strong> <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-IMAGE_INSTALL' target='_blank'>Read more in the manual</a>"></i>
- </dt>
- <dd class="lead">
- <span id="image_install"{% if image_install_append %}{%else%} class="muted"{%endif%}>{% if image_install_append %}{{image_install_append}}{%else%}Not set{%endif%}</span>
- <i class="icon-pencil" id="change-image_install-icon"></i>
- <i class="icon-trash" id="delete-image_install-icon" {% if image_install_append %}{%else%}style="display:none;"{%endif%}></i>
- <form id="change-image_install-form" style="display:none;">
- <div class="row-fluid">
- <span class="help-block span4">To set IMAGE_INSTALL_append to more than one package, type the package names separated by a space.</span>
- </div>
- <div class="input-append">
- <input type="text" class="input-xlarge" id="new-image_install" placeholder="Type one or more package names">
- <button id="apply-change-image_install" class="btn" type="button">Save</button>
- <button id="cancel-change-image_install" type="button" class="btn btn-link">Cancel</button>
- </div>
- </form>
- </dd>
- {% endif %}
-
- {% if package_classes_defined %}
- <dt>
- <span class="js-config-var-name js-config-var-managed-name">PACKAGE_CLASSES</span>
- <i class="icon-question-sign get-help" title="Specifies the package manager to use when packaging data <br /><a href='http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-PACKAGE_CLASSES' target='_blank'>Read more in the manual</a>"></i>
- </dt>
- <dd class="lead">
- <span id="package_classes">{{package_classes}}</span>
- <i id="change-package_classes-icon" class="icon-pencil"></i>
- <form id="change-package_classes-form" style="display:none;">
- <label>
- Root file system package format
- <i class="icon-question-sign get-help" title="The package format used to generate the root file system. Options are <code>dev</code>, <code>ipk</code> and <code>rpm</code>"></i>
- </label>
- <select id="package_classes-select">
- <option>package_deb</option>
- <option>package_ipk</option>
- <option>package_rpm</option>
- </select>
- <label>
- Additional package formats
- <i class="icon-question-sign get-help" title="Extra package formats to build"></i>
- </label>
- <label class="checkbox" id="package_class_1">
- <input type="checkbox" id="package_class_1_input"> package_deb
- </label>
- <label class="checkbox" id="package_class_2">
- <input type="checkbox" id="package_class_2_input"> package_ipk
- </label>
- <div style="padding-top:10px;">
- <button id="apply-change-package_classes" type="button" class="btn">Save</button>
- <button id="cancel-change-package_classes" type="button" class="btn btn-link">Cancel</button>
- </div>
- </form>
- </dd>
- {% endif %}
-
- {% if sstate_dir_defined %}
- <dt>
- <span class="js-config-var-name js-config-var-managed-name">SSTATE_DIR</span>
- <i class="icon-question-sign get-help" title="Absolute path to the directory used to store shared state cache files. These files are reused across the builds, which makes the builds faster. By default, Toaster projects share the same cache directory.<br /><a href='http://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#var-SSTATE_DIR' target='_blank'>Read more in the manual</a>"></i>
- </dt>
- <dd class="lead">
- <span id="sstate_dir"{% if sstate_dir %}{%else%} class="muted"{%endif%}>{% if sstate_dir %}{{sstate_dir}}{%else%}Not set{%endif%}</span>
- <i class="icon-pencil" id="change-sstate_dir-icon"></i>
- <form id="change-sstate_dir-form" style="display:none;">
- <div class="row-fluid">
- <span class="help-block span4">To set SSTATE_DIR type the absolute path of the download folder.</span>
- </div>
- <div class="input-append" id="validate-sstate_dir">
- <input type="text" class="input-xlarge" id="new-sstate_dir" placeholder="Type absolute path of the SSTATE_DIR folder">
- <span class="error">A valid directory name required</span>
- <button id="apply-change-sstate_dir" class="btn" type="button">Save</button>
- <button id="cancel-change-sstate_dir" type="button" class="btn btn-link">Cancel</button>
- </br><p class="help-block error" id="hintError-sstate_dir">A valid directory cannot include spaces or any of these characters: . \ ? % * : | " " < ></span>
- </div>
- </form>
- </dd>
- {% endif %}
- </dl>
-
- <!-- <ul class="unstyled configuration-list" id="configvar-list"> -->
- <dl id="configvar-list">
- <!-- the added configuration variables are inserted here -->
- </dl>
-
- <!-- pass the fstypes list, black list, and externally managed variables here -->
- {% for fstype in vars_fstypes %}
- <input type="hidden" class="js-checkbox-fstypes-list" value="{{fstype}}">
- {% endfor %}
- {% for b in vars_blacklist %}
- <input type="hidden" class="js-config-blacklist-name" value="{{b}}">
- {% endfor %}
- {% for b in vars_managed %}
- <input type="hidden" class="js-config-managed-name" value="{{b}}">
- {% endfor %}
-
- <div class="row-fluid">
- <form id="variable-form">
- <fieldset style="padding-left:0px;">
- <legend>Add variable</legend>
- <div class="span3" style="margin-left:0px;">
- <span id="add-configvar-name-div" class="control-group">
- <label>
- Variable
- <i title="" class="icon-question-sign get-help"
- data-original-title="Variable names are case sensitive,
- cannot have spaces, and can only include letters, numbers, underscores
- and dashes"></i>
- </label>
- <input type="text" placeholder="Type variable name" id="variable">
- <span class="help-block error" id="new-variable-error-message"></span>
- </span>
- <label>Value</label>
- <input id="value" type="text" placeholder="Type variable value"><p>
- <div>
- <button id="add-configvar-button" class="btn save" type="button" disabled>Add variable</button>
- </div>
- </div>
- <div class="span5 help-block">
- <h5>Some variables are reserved from Toaster</h5>
- <p>Toaster cannot set any variables that impact 1) the configuration of the build servers,
- or 2) where artifacts produced by the build are stored. Such variables include: </p>
- <p>
- <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-BB_DISKMON_DIRS" target="_blank">BB_DISKMON_DIRS</a></code>
- <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-BB_NUMBER_THREADS" target="_blank">BB_NUMBER_THREADS</a></code>
- <code>CVS_PROXY_HOST</code>
- <code>CVS_PROXY_PORT</code>
- <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-PARALLEL_MAKE" target="_blank">PARALLEL_MAKE</a></code>
- <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-SSTATE_MIRRORS" target="_blank">SSTATE_MIRRORS</a></code>
- <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-TMPDIR" target="_blank">TMPDIR</a></code></p>
- <p>Plus the following standard shell environment variables:</p>
- <p><code>http_proxy</code> <code>ftp_proxy</code> <code>https_proxy</code> <code>all_proxy</code></p>
- </div>
- </fieldset>
- </form>
+<div>
+ <dl>
+ {% if distro_defined %}
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">DISTRO</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The short name of the distribution. If the variable is blank, meta/conf/distro/defaultsetup.conf will be used"></span>
+ </dt>
+ <dd class="variable-list">
+ <span class="lead" id="distro">{{distro}}</span>
+ <span class="glyphicon glyphicon-edit" id="change-distro-icon"></span>
+ <form id="change-distro-form" class="form-inline" style="display:none;">
+ <div id="edit-distro-name-div" class="form-group">
+ <input type="text" class="form-control" id="new-distro" value="{{distro}}">
+ </div>
+ <button id="apply-change-distro" class="btn btn-default" type="button">Save</button>
+ <button id="cancel-change-distro" type="button" class="btn btn-link">Cancel</button>
+ <span class="help-block" id="distro-error-message"></span>
+ </form>
+ </dd>
+ {% endif %}
+
+ {% if dl_dir_defined %}
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">DL_DIR</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Absolute path to the directory used to store downloads required for your builds. By default, Toaster projects share the same downloads directory"></span>
+ </dt>
+ <dd class="variable-list">
+ <span id="dl_dir" class="lead {% if not dl_dir %} text-muted {% endif %}">{% if dl_dir %}{{dl_dir}}{%else%}Not set{%endif%}</span>
+ <span class="glyphicon glyphicon-edit" id="change-dl_dir-icon"></span>
+ <form id="change-dl_dir-form" class="form-inline" style="display:none;">
+ <div class="form-group" id="validate-dl_dir">
+ <input type="text" class="form-control" id="new-dl_dir" placeholder="Type an absolute path">
+ </div>
+ <button id="apply-change-dl_dir" class="btn btn-default" type="button">Save</button>
+ <button id="cancel-change-dl_dir" type="button" class="btn btn-link">Cancel</button>
+ <p class="help-block" id="hintError-dl_dir" style="display:none;">The directory path cannot include spaces or any of these characters: . \ ? % * : | " " &lt; &gt;</p>
+ <p class="help-block" id="hintError-initialChar-dl_dir" style="display:none;">The directory path should either start with a /, e.g. /home/toaster/downloads; or with a variable, e.g. ${TOPDIR}/downloads.</p>
+ </form>
+ </dd>
+ {% endif %}
+
+ {% if fstypes_defined %}
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">IMAGE_FSTYPES</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Formats of root file system images that you want to create"></span>
+ </dt>
+ <dd class="variable-list">
+ <span class="lead" id="image_fstypes">{{fstypes}}</span>
+ <span class="glyphicon glyphicon-edit" id="change-image_fstypes-icon"></span>
+ <form id="change-image_fstypes-form" style="display:none;">
+ <label>Type the image types you want to build:</label>
+ <div class="form-group form-inline" id="validate-image_fstypes">
+ <input type="text" class="form-control "id="new-imagefs_types">
+ <button id="apply-change-image_fstypes" type="button" class="btn btn-default">Save</button>
+ <button id="cancel-change-image_fstypes" type="button" class="btn btn-link">Cancel</button>
+ </div>
+ <p class="help-block text-danger" style="display:none;" id="hintError-image-fs_type">A valid image type cannot include underscores</p>
+ <label>Or choose from known image types:</label>
+ <input id="filter-image_fstypes" type="text" placeholder="Search image types" class="form-control">
+ <div id="all-image_fstypes" class="scrolling"></div>
+ </form>
+ </dd>
+ {% endif %}
+
+ {% if image_install_append_defined %}
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">IMAGE_INSTALL_append</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Specifies additional packages to install into an image. If your build creates more than one image, the packages will be installed in all of them"></span>
+ </dt>
+ <dd class="variable-list">
+ <span id="image_install" class="lead {% if not image_install_append %} text-muted {%endif%}">{% if image_install_append %}{{image_install_append}}{%else%}Not set{%endif%}</span>
+ <span class="glyphicon glyphicon-edit" id="change-image_install-icon"></span>
+ <span class="glyphicon glyphicon-trash" id="delete-image_install-icon" {% if image_install_append %}{%else%}style="display:none;"{%endif%}></span>
+ <form id="change-image_install-form" class="form-inline" style="display:none;">
+ <div class="row">
+ <div class="col-md-4">
+ <span class="help-block">To set IMAGE_INSTALL_append to more than one package, type the package names separated by a space.</span>
</div>
-
- </div>
-
- <script>
-
- // global variables
- var do_reload=false;
-
- // validate new variable name
- function validate_new_variable() {
- var variable = $("input#variable").val();
- var value = $("input#value").val();
-
- // presumed innocence
- $('#new-variable-error-message').text("");
- var error_msg = "";
-
- var existing_configvars = document.getElementsByClassName('js-config-var-name');
- for (var i = 0, length = existing_configvars.length; i < length; i++) {
- if (existing_configvars[i].innerHTML.toUpperCase() == variable.toUpperCase()) {
- error_msg = "This variable is already set in this page, edit its value instead";
- }
- }
-
- var blacklist_configvars = document.getElementsByClassName('js-config-blacklist-name');
- for (var i = 0, length = blacklist_configvars.length; i < length; i++) {
- if (blacklist_configvars[i].value.toUpperCase() == variable.toUpperCase()) {
- error_msg = "You cannot edit this variable in Toaster because it is set by the build servers";
- }
- }
-
- var managed_configvars = document.getElementsByClassName('js-config-managed-name');
- for (var i = 0, length = managed_configvars.length; i < length; i++) {
- if (managed_configvars[i].value.toUpperCase() == variable.toUpperCase()) {
- error_msg = "You cannot set this variable here. Please set it in the <a href=\"{% url 'project' project.id %}\">project main page</a>";
- }
- }
-
- var bad_chars = /[^a-zA-Z0-9\-_]/.test(variable);
- var has_spaces = (0 <= variable.indexOf(" "));
- var only_spaces = (0 < variable.length) && (0 == variable.trim().length);
-
- if (only_spaces) {
- error_msg = "A valid variable name cannot include spaces";
- } else if (bad_chars && has_spaces) {
- error_msg = "A valid variable name can only include letters, numbers, underscores, dashes, and cannot include spaces";
- } else if (bad_chars) {
- error_msg = "A valid variable name can only include letters, numbers, underscores, and dashes";
- }
-
- if ("" != error_msg) {
- $('#new-variable-error-message').html(error_msg);
- $(".save").attr("disabled","disabled");
-
- // add one (and only one) error class append
- var d = document.getElementById("add-configvar-name-div");
- d.className = d.className.replace(" error","");
- d.className = d.className + " error";
-
- return false;
- } else if (0 == variable.length) {
- $(".save").attr("disabled","disabled");
- return false;
- }
-
- var d = document.getElementById("add-configvar-name-div");
- d.className = d.className.replace(" error","");
-
- // now set the "Save" enablement if 'value' also passes
- if (value.trim().length > 0) {
- $(".save").removeAttr("disabled");
- } else {
- $(".save").attr("disabled","disabled");
- }
-
- return true;
- }
-
- // validate distro name
- function validate_distro_name() {
- var value = $("input#new-distro").val();
-
- // presumed innocence
- $('#distro-error-message').text("");
- var error_msg = "";
-
- var has_spaces = (0 <= value.indexOf(" "));
-
- if (has_spaces) {
- error_msg = "A valid distro name cannot include spaces";
- } else if (0 == value.length) {
- error_msg = " ";
- }
-
- if ("" != error_msg) {
- $('#distro-error-message').text(error_msg);
- $("#apply-change-distro").attr("disabled","disabled");
-
- // add one (and only one) error class append
- var d = document.getElementById("edit-distro-name-div");
- d.className = d.className.replace(" error","");
- d.className = d.className + " error";
-
- return false;
- }
-
- var d = document.getElementById("edit-distro-name-div");
- d.className = d.className.replace(" error","");
- $("#apply-change-distro").removeAttr("disabled");
- return true;
- }
-
- // Test to insure at least one FS Type is checked
- function enableFsTypesSave() {
- var any_checked = 0;
- $(".fs-checkbox-fstypes:checked").each(function(){
- any_checked = 1;
- });
- if ( 0 == any_checked ) {
- $("#apply-change-image_fstypes").attr("disabled","disabled");
- $('#fstypes-error-message').show();
- }
- else {
- $("#apply-change-image_fstypes").removeAttr("disabled");
- $('#fstypes-error-message').hide();
- }
- }
-
- // Preset or reset the Package Class checkbox labels
- function updatePackageClassCheckboxes() {
- $('#package_class_1, #package_class_2').hide();
- if ($('select').val() == 'package_deb') {
- $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_ipk');
- $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
- }
- if ($('select').val() == 'package_ipk') {
- $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb');
- $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
- }
- if ($('select').val() == 'package_rpm') {
- $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb');
- $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_ipk');
- }
- $('#package_class_1, #package_class_2').fadeIn(1500);
- }
-
- // Re-assert handlers when the page is served and/or refreshed via Ajax
- function setEventHandlersForDynamicElements() {
-
- // change variable value
- $('.js-icon-pencil-config_var').click(function (evt) {
- var pk = evt.target.attributes["x-data"].value;
- var current_val = $("span#config_var_value_"+pk).text();
- $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).hide();
- $("#change-config_var-form_"+pk).slideDown();
- $("input#new-config_var_"+pk).val(current_val);
- });
-
- $('.js-cancel-change-config_var').click(function (evt) {
- var pk = evt.target.attributes["x-data"].value;
- $("#change-config_var-form_"+pk).slideUp(function() {
- $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).show();
- });
- });
-
- $(".js-new-config_var").on('input', function(){
- if ($(this).val().length == 0) {
- $(".js-apply-change-config_var").attr("disabled","disabled");
- }
- else {
- $(".js-apply-change-config_var").removeAttr("disabled");
- }
- });
-
- $('.js-apply-change-config_var').click(function (evt) {
- var xdata = evt.target.attributes["x-data"].value.split(":");
- var pk = xdata[0];
- var variable = xdata[1];
- var val = $('#new-config_var_'+pk).val();
- postEditAjaxRequest({"configvarChange" : variable+':'+val});
- $('#config_var_value_'+pk).parent().removeClass('muted');
- $("#change-config_var-form_"+pk).slideUp(function() {
- $('.js-icon-pencil-config_var, .js-icon-trash-config_var, #config_var_value_'+pk).show();
- });
- });
-
- // delete variable
- $(".js-icon-trash-config_var").click(function (evt) {
- var xdata = evt.target.attributes["x-data"].value.split(":");
- var pk = xdata[0];
-
- // hide the dangling trash tooltip
- $('#config_var_trash_'+pk).hide();
-
- // fade out the variable+value div, then refresh the variable list
- $('#config_var_entry_'+pk).parent().parent().fadeOut(1000, function(){
- postEditAjaxRequest({"configvarDel": evt.target.attributes["x-data"].value});
- });
-
- });
-
- }
-
- function onEditPageUpdate(data) {
- // update targets
- var i; var orightml = "";
-
- var configvars_sorted = data.configvars.sort(function(a, b){return a[0] > b[0]});
-
- var managed_configvars = document.getElementsByClassName('js-config-var-managed-name');
-
- for (i = 0; i < configvars_sorted.length; i++) {
- // skip if the variable name has a special context (not user defined)
- var var_context=undefined;
- for (var j = 0, length = managed_configvars.length; j < length; j++) {
- if ((managed_configvars[j].innerHTML == configvars_sorted[i][0]) ||
- (managed_configvars[j].value == configvars_sorted[i][0]) ) {
- var_context='m';
- }
- }
- if (var_context == undefined) {
- orightml += '<div> <dt><span id="config_var_entry_'+configvars_sorted[i][2]+'" class="js-config-var-name"></span><i class="icon-trash js-icon-trash-config_var" id="config_var_trash_'+configvars_sorted[i][2]+'" x-data="'+configvars_sorted[i][2]+'"></i> </dt>'
- orightml += '<dd class="lead">'
- orightml += ' <span id="config_var_value_'+configvars_sorted[i][2]+'"></span>'
- orightml += ' <i class="icon-pencil js-icon-pencil-config_var" x-data="'+configvars_sorted[i][2]+'"></i>'
- orightml += ' <form id="change-config_var-form_'+configvars_sorted[i][2]+'" style="display:none;">'
- orightml += ' <div class="input-append">'
- orightml += ' <input type="text" class="input-xlarge js-new-config_var" id="new-config_var_'+configvars_sorted[i][2]+'" value="">'
- orightml += ' <button class="btn js-apply-change-config_var" type="button" x-data="'+configvars_sorted[i][2]+':'+configvars_sorted[i][0]+'" disabled>Save</button>'
- orightml += ' <button type="button" class="btn btn-link js-cancel-change-config_var" x-data="'+configvars_sorted[i][2]+'">Cancel</button>'
- orightml += ' </div>'
- orightml += ' </form>'
- orightml += '</dd> </div>'
- }
- }
-
- // update configvars list HTML framework
- $("dl#configvar-list").html(orightml);
-
- // insert the name/value pairs safely as non-HTML
- for (i = 0; i < configvars_sorted.length; i++) {
- $('#config_var_entry_'+configvars_sorted[i][2]).text(configvars_sorted[i][0]);
- $('#config_var_value_'+configvars_sorted[i][2]).text(configvars_sorted[i][1]);
- }
-
- // Add the tooltips
- $(".js-icon-trash-config_var").each( function(){ setDeleteTooltip($(this)); });
- $(".js-icon-pencil-config_var").each(function(){ setChangeTooltip($(this)); });
-
- // re-assert these event handlers
- setEventHandlersForDynamicElements();
- }
-
- function onEditAjaxSuccess(data, textstatus) {
- // console.log("XHR returned:", data, "(" + textstatus + ")");
- if (data.error != "ok") {
- alert("error on request:\n" + data.error);
- return;
- }
-
- // delayed page reload?
- if (do_reload) {
- do_reload=false;
- location.reload(true);
- } else {
- onEditPageUpdate(data);
- }
- }
-
- function onEditAjaxError(jqXHR, textstatus, error) {
- alert("XHR errored:\n" + error + "\n(" + textstatus + ")");
- // re-assert the event handlers
- }
-
- /* ensure cookie exists {% csrf_token %} */
- function postEditAjaxRequest(reqdata) {
- var ajax = $.ajax({
- type:"POST",
- data: $.param(reqdata),
- url:"{% url 'xhr_configvaredit' project.id%}",
- headers: { 'X-CSRFToken': $.cookie("csrftoken")},
- success: onEditAjaxSuccess,
- error: onEditAjaxError,
- })
- }
-
- function setDeleteTooltip(object) {
- object.tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Delete" });
- }
- function setChangeTooltip(object) {
- object.tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Change" });
+ </div>
+ <div class="form-group">
+ <input type="text" class="form-control" id="new-image_install" placeholder="Type one or more package names">
+ </div>
+ <button id="apply-change-image_install" class="btn btn-default" type="button">Save</button>
+ <button id="cancel-change-image_install" type="button" class="btn btn-link">Cancel</button>
+ </form>
+ </dd>
+ {% endif %}
+
+ {% if package_classes_defined %}
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">PACKAGE_CLASSES</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Specifies the package manager to use when packaging data"></span>
+ </dt>
+ <dd class="variable-list">
+ <span class="lead" id="package_classes">{{package_classes}}</span>
+ <span id="change-package_classes-icon" class="glyphicon glyphicon-edit"></span>
+ <form id="change-package_classes-form" style="display:none;">
+ <div class="form-group">
+ <label class="control-label">
+ Root file system package format
+ <span class="glyphicon glyphicon-question-sign get-help" title="The package format used to generate the root file system. Options are <code>deb</code>, <code>ipk</code> and <code>rpm</code>"></i>
+ </label>
+ <select id="package_classes-select" class="form-control">
+ <option>package_deb</option>
+ <option>package_ipk</option>
+ <option>package_rpm</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <label class="control-label">
+ Additional package formats
+ <span class="glyphicon glyphicon-question-sign get-help" title="Extra package formats to build"></span>
+ </label>
+ <div class="checkbox">
+ <label id="package_class_1">
+ <input type="checkbox" id="package_class_1_input"> package_deb
+ </label>
+ </div>
+ <div class="checkbox">
+ <label id="package_class_2">
+ <input type="checkbox" id="package_class_2_input"> package_ipk
+ </label>
+ </div>
+ </div>
+ <button id="apply-change-package_classes" type="button" class="btn btn-default">Save</button>
+ <button id="cancel-change-package_classes" type="button" class="btn btn-link">Cancel</button>
+ </form>
+ </dd>
+ {% endif %}
+
+ {% if sstate_dir_defined %}
+ <dt>
+ <span class="js-config-var-name js-config-var-managed-name">SSTATE_DIR</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Absolute path to the directory used to store shared state cache files. These files are reused across the builds, which makes the builds faster. By default, Toaster projects share the same cache directory"></span>
+ </dt>
+ <dd class="variable-list">
+ <span id="sstate_dir" class="lead {% if not sstate_dir %} text-muted {% endif %}">{% if sstate_dir %}{{sstate_dir}}{%else%}Not set{%endif%}</span>
+ <span class="glyphicon glyphicon-edit" id="change-sstate_dir-icon"></span>
+ <form class="form-inline" id="change-sstate_dir-form" style="display:none;">
+ <div class="form-group" id="validate-sstate_dir">
+ <input type="text" class="form-control" id="new-sstate_dir" placeholder="Type an absolute path">
+ </div>
+ <button id="apply-change-sstate_dir" class="btn btn-default" type="button">Save</button>
+ <button id="cancel-change-sstate_dir" type="button" class="btn btn-link">Cancel</button>
+ <p class="help-block" id="hintError-sstate_dir" style="display:none;">The directory path cannot include spaces or any of these characters: . \ ? % * : | " " &lt; &gt;</p>
+ <p class="help-block" id="hintError-initialChar-sstate_dir" style="display:none;">The directory path should either start with a /, e.g. /home/toaster/sstate-cache; or with a variable, e.g. ${TOPDIR}/sstate-cache.</p>
+ </form>
+ </dd>
+ {% endif %}
+ </dl>
+
+ <!-- <ul class="list-unstyled configuration-list" id="configvar-list"> -->
+ <dl id="configvar-list">
+ <!-- the added configuration variables are inserted here -->
+ </dl>
+
+ <!-- pass the fstypes list, black list, and externally managed variables here -->
+ {% for fstype in vars_fstypes %}
+ <input type="hidden" class="js-checkbox-fstypes-list" value="{{fstype}}">
+ {% endfor %}
+ {% for b in vars_blacklist %}
+ <input type="hidden" class="js-config-blacklist-name" value="{{b}}">
+ {% endfor %}
+ {% for b in vars_managed %}
+ <input type="hidden" class="js-config-managed-name" value="{{b}}">
+ {% endfor %}
+
+ <form id="variable-form">
+ <fieldset>
+ <legend>Add variable</legend>
+ <div class="row">
+ <div class="col-md-3">
+ <div id="add-configvar-name-div" class="form-group">
+ <label class="control-label">
+ Variable
+ <span class="glyphicon glyphicon-question-sign get-help"
+ title="Variable names are case sensitive,
+ cannot have spaces, and can only include letters, numbers, underscores
+ and dashes"></span>
+ </label>
+ <input type="text" class="form-control" placeholder="Type the variable name" id="variable">
+ </div>
+ <p class="help-block" id="new-variable-error-message"></p>
+ <div class="form-group">
+ <label clas="control-label">Value</label>
+ <input id="value" type="text" class="form-control" placeholder="Type the variable value">
+ </div>
+ <button id="add-configvar-button" class="btn btn-default save" type="button" disabled>Add variable</button>
+ </div>
+ <div class="col-md-5 help-block">
+ <h5>Some variables cannot be set from Toaster</h5>
+ <p>Toaster cannot set any variables that impact 1) the configuration of the build servers,
+ or 2) where artifacts produced by the build are stored. Such variables include: </p>
+ <p>
+ <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-BB_DISKMON_DIRS" target="_blank">BB_DISKMON_DIRS</a></code>
+ <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-BB_NUMBER_THREADS" target="_blank">BB_NUMBER_THREADS</a></code>
+ <code>CVS_PROXY_HOST</code>
+ <code>CVS_PROXY_PORT</code>
+ <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-PARALLEL_MAKE" target="_blank">PARALLEL_MAKE</a></code>
+ <code><a href="http://www.yoctoproject.org/docs/1.6.1/ref-manual/ref-manual.html#var-TMPDIR" target="_blank">TMPDIR</a></code></p>
+ <p>Plus the following standard shell environment variables:</p>
+ <p><code>http_proxy</code> <code>ftp_proxy</code> <code>https_proxy</code> <code>all_proxy</code></p>
+ </div>
+ </div>
+ </fieldset>
+ </form>
+</div>
+
+</div>
+
+<script>
+
+// global variables
+var do_reload=false;
+
+// validate new variable name
+function validate_new_variable() {
+ var variable = $("input#variable").val();
+ var value = $("input#value").val();
+
+ // presumed innocence
+ $('#new-variable-error-message').text("");
+ var error_msg = "";
+
+ var existing_configvars = document.getElementsByClassName('js-config-var-name');
+ for (var i = 0, length = existing_configvars.length; i < length; i++) {
+ if (existing_configvars[i].innerHTML.toUpperCase() == variable.toUpperCase()) {
+ error_msg = "This variable is already set in this page. Edit its value instead";
+ }
+ }
+
+ var blacklist_configvars = document.getElementsByClassName('js-config-blacklist-name');
+ for (var i = 0, length = blacklist_configvars.length; i < length; i++) {
+ if (blacklist_configvars[i].value.toUpperCase() == variable.toUpperCase()) {
+ error_msg = "You cannot edit this variable in Toaster because it is set by the build servers";
+ }
+ }
+
+ var managed_configvars = document.getElementsByClassName('js-config-managed-name');
+ for (var i = 0, length = managed_configvars.length; i < length; i++) {
+ if (managed_configvars[i].value.toUpperCase() == variable.toUpperCase()) {
+ error_msg = "You cannot set this variable here. Please set it in the <a href=\"{% url 'project' project.id %}\">project main page</a>";
+ }
+ }
+
+ var bad_chars = /[^a-zA-Z0-9\-_/]/.test(variable);
+ var has_spaces = (0 <= variable.indexOf(" "));
+ var only_spaces = (0 < variable.length) && (0 == variable.trim().length);
+
+ if (only_spaces) {
+ error_msg = "A valid variable name cannot include spaces";
+ } else if (bad_chars && has_spaces) {
+ error_msg = "A valid variable name can only include letters, numbers and the special characters <code> _ - /</code>. Variable names cannot include spaces";
+ } else if (bad_chars) {
+ error_msg = "A valid variable name can only include letters, numbers and the special characters <code>_ - /</code>";
+ }
+
+ if ("" != error_msg) {
+ $('#new-variable-error-message').html(error_msg);
+ $(".save").attr("disabled","disabled");
+
+ // add one (and only one) error class append
+ $("#add-configvar-name-div").addClass("has-error");
+ $("#new-variable-error-message").addClass("text-danger");
+
+ return false;
+ } else if (0 == variable.length) {
+ $(".save").attr("disabled","disabled");
+ return false;
+ }
+
+ $("#add-configvar-name-div").removeClass("has-error");
+
+ // now set the "Save" enablement if 'value' also passes
+ if (value.trim().length > 0) {
+ $(".save").removeAttr("disabled");
+ } else {
+ $(".save").attr("disabled","disabled");
+ }
+
+ return true;
+}
+
+// validate distro name
+function validate_distro_name() {
+ var value = $("input#new-distro").val();
+
+ // presumed innocence
+ $('#distro-error-message').text("");
+ var error_msg = "";
+
+ var has_spaces = (0 <= value.indexOf(" "));
+
+ if (has_spaces) {
+ error_msg = "A valid distro name cannot include spaces";
+ } else if (0 == value.length) {
+ error_msg = " ";
+ }
+
+ if ("" != error_msg) {
+ $('#distro-error-message').text(error_msg);
+ $("#apply-change-distro").attr("disabled","disabled");
+
+ // add one (and only one) error class append
+ $("#change-distro-form").addClass("has-error");
+
+ return false;
+ }
+
+ $("#change-distro-form").removeClass("has-error");
+ $("#apply-change-distro").removeAttr("disabled");
+ return true;
+}
+
+// Test to insure at least one FS Type is checked
+function enableFsTypesSave() {
+ var any_checked = 0;
+ $(".fs-checkbox-fstypes:checked").each(function(){
+ any_checked = 1;
+ });
+ if ( 0 == any_checked ) {
+ $("#apply-change-image_fstypes").attr("disabled","disabled");
+ $('.scrolling').addClass('has-error');
+ $('#fstypes-error-message').show();
+ }
+ else {
+ $("#apply-change-image_fstypes").removeAttr("disabled");
+ $('.scrolling').removeClass('has-error');
+ $('#fstypes-error-message').hide();
+ }
+}
+
+// Preset or reset the Package Class checkbox labels
+function updatePackageClassCheckboxes() {
+ $('#package_class_1, #package_class_2').hide();
+ if ($('select').val() == 'package_deb') {
+ $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_ipk');
+ $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
+ }
+ if ($('select').val() == 'package_ipk') {
+ $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb');
+ $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_rpm');
+ }
+ if ($('select').val() == 'package_rpm') {
+ $('#package_class_1').html('<input type="checkbox" id="package_class_1_input"> package_deb');
+ $('#package_class_2').html('<input type="checkbox" id="package_class_2_input"> package_ipk');
+ }
+ $('#package_class_1, #package_class_2').fadeIn(1500);
+}
+
+// Re-assert handlers when the page is served and/or refreshed via Ajax
+function setEventHandlersForDynamicElements() {
+
+ // change variable value
+ $('.js-icon-pencil-config_var').click(function (evt) {
+ var pk = $(this).attr("x-data");
+ var current_val = $("#config_var_value_"+pk).text();
+ $("#config_var_value_"+pk).hide();
+ $("#config_var_trash_"+pk).hide();
+ $(".js-icon-pencil-config_var[x-data="+pk+"]").hide();
+ $("#change-config_var-form_"+pk).slideDown();
+ $("#new-config_var_"+pk).val(current_val);
+ if ( $("#new-config_var_"+pk).val().length ) {
+ $("#apply-change-config_var_"+pk).removeAttr("disabled");
+ }
+ else {
+ $("#apply-change-config_var_"+pk).attr("disabled");
+ }
+ });
+
+ $('.js-cancel-change-config_var').click(function (evt) {
+ var pk = evt.target.attributes["x-data"].value;
+ $("#change-config_var-form_"+pk).slideUp(function() {
+ $("#config_var_trash_"+pk).show();
+ $('#config_var_value_'+pk).show();
+ $(".js-icon-pencil-config_var[x-data="+pk+"]").show();
+ });
+ });
+
+ $(".js-new-config_var").on('input', function(){
+ if ($(this).val().length == 0) {
+ $(this).parent("div").next(".btn-default").attr("disabled","disabled");
+ }
+ else {
+ $(this).parent("div").next(".btn-default").removeAttr("disabled");
+ }
+ });
+
+ $('.js-apply-change-config_var').click(function (evt) {
+ var xdata = evt.target.attributes["x-data"].value.split(":");
+ var pk = xdata[0];
+ var variable = xdata[1];
+ var val = $('#new-config_var_'+pk).val();
+ postEditAjaxRequest({"configvarChange" : variable+':'+val});
+ $("#change-config_var-form_"+pk).slideUp();
+ $("#config_var_trash_"+pk).fadeIn();
+ $('#config_var_value_'+pk).fadeIn();
+ $(".js-icon-pencil-config_var[x-data="+pk+"]").fadeIn();
+ });
+
+ // delete variable
+ $(".js-icon-trash-config_var").click(function (evt) {
+ var pk = $(this).attr("x-data");
+
+ // fade out the variable+value div, then refresh the variable list
+ $(this).fadeOut();
+ $(this).tooltip("hide");
+ $("config_var_entry_"+pk).fadeOut();
+ $('#config_var_value_'+pk).parent("dd").fadeOut();
+ postEditAjaxRequest({"configvarDel": evt.target.attributes["x-data"].value});
+ });
+
+}
+
+function onEditPageUpdate(data) {
+ // update targets
+ var i; var orightml = "";
+
+ var configvars_sorted = data.configvars.sort(function(a, b){return a[0] > b[0]});
+
+ var managed_configvars = document.getElementsByClassName('js-config-var-managed-name');
+
+ for (i = 0; i < configvars_sorted.length; i++) {
+ // skip if the variable name has a special context (not user defined)
+ var var_context=undefined;
+ for (var j = 0, length = managed_configvars.length; j < length; j++) {
+ if ((managed_configvars[j].innerHTML == configvars_sorted[i][0]) ||
+ (managed_configvars[j].value == configvars_sorted[i][0]) ) {
+ var_context='m';
+ }
+ }
+ if (var_context == undefined) {
+ orightml += '<dt><span id="config_var_entry_'+configvars_sorted[i][2]+'" class="js-config-var-name"></span><span class="glyphicon glyphicon-trash js-icon-trash-config_var" id="config_var_trash_'+configvars_sorted[i][2]+'" x-data="'+configvars_sorted[i][2]+'"></span> </dt>'
+ orightml += '<dd class="variable-list">'
+ orightml += ' <span class="lead" id="config_var_value_'+configvars_sorted[i][2]+'"></span>'
+ orightml += ' <span class="glyphicon glyphicon-edit js-icon-pencil-config_var" x-data="'+configvars_sorted[i][2]+'"></span>'
+ orightml += ' <form class="form-inline" id="change-config_var-form_'+configvars_sorted[i][2]+'" style="display:none;">'
+ orightml += ' <div class="form-group">'
+ orightml += ' <input type="text" class="form-control js-new-config_var" id="new-config_var_'+configvars_sorted[i][2]+'" value=""></div>'
+ orightml += ' <button id="apply-change-config_var_'+configvars_sorted[i][2]+'" class="btn btn-default js-apply-change-config_var" type="button" x-data="'+configvars_sorted[i][2]+':'+configvars_sorted[i][0]+'" disabled>Save</button>'
+ orightml += ' <button type="button" class="btn btn-link js-cancel-change-config_var" x-data="'+configvars_sorted[i][2]+'">Cancel</button>'
+ orightml += ' </form>'
+ orightml += '</dd>'
+ }
+ }
+
+ // update configvars list HTML framework
+ $("dl#configvar-list").html(orightml);
+
+ // insert the name/value pairs safely as non-HTML
+ for (i = 0; i < configvars_sorted.length; i++) {
+ $('#config_var_entry_'+configvars_sorted[i][2]).text(configvars_sorted[i][0]);
+ $('#config_var_value_'+configvars_sorted[i][2]).text(configvars_sorted[i][1]);
+ }
+
+ // Add the tooltips
+ $(".js-icon-trash-config_var").each( function(){ setDeleteTooltip($(this)); });
+ $(".js-icon-pencil-config_var").each(function(){ setChangeTooltip($(this)); });
+
+ // re-assert these event handlers
+ setEventHandlersForDynamicElements();
+}
+
+function onEditAjaxSuccess(data, textstatus) {
+ console.log("XHR returned:", data, "(" + textstatus + ")");
+ if (data.error != "ok") {
+ alert("error on request:\n" + data.error);
+ return;
+ }
+
+ // delayed page reload?
+ if (do_reload) {
+ do_reload=false;
+ location.reload(true);
+ } else {
+ onEditPageUpdate(data);
+ }
+}
+
+function onEditAjaxError(jqXHR, textstatus, error) {
+ alert("XHR errored:\n" + error + "\n(" + textstatus + ")");
+ // re-assert the event handlers
+}
+
+/* ensure cookie exists {% csrf_token %} */
+function postEditAjaxRequest(reqdata) {
+ var ajax = $.ajax({
+ type:"POST",
+ data: $.param(reqdata),
+ url:"{% url 'xhr_configvaredit' project.id%}",
+ headers: { 'X-CSRFToken': $.cookie("csrftoken")},
+ success: onEditAjaxSuccess,
+ error: onEditAjaxError,
+ })
+}
+
+function setDeleteTooltip(object) {
+ object.tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Delete" });
+}
+function setChangeTooltip(object) {
+ object.tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Change" });
+}
+
+$(document).ready(function() {
+
+ //
+ // Register handlers for static elements
+ //
+
+ {% if distro_defined %}
+ // change distro variable
+ $('#change-distro-icon').click(function() {
+ $('#change-distro-icon, #distro').hide();
+ $("#change-distro-form").slideDown();
+ $("#new-distro").val( $('#distro').text() );
+ $("#apply-change-distro").removeAttr("disabled");
+ });
+
+ $('#cancel-change-distro').click(function(){
+ $("#change-distro-form").slideUp(function() {
+ $('#distro, #change-distro-icon').show();
+
+ // reset any dangling error state
+ $('#distro-error-message').text("");
+ $("#change-distro-form").removeClass("has-error");
+ });
+ });
+
+ // validate new distro name
+ $("input#new-distro").on('input', function (evt) {
+ validate_distro_name();
+ });
+
+ $('#apply-change-distro').click(function(){
+ //$('#repo').parent().removeClass('highlight-go');
+ var name = $('#new-distro').val();
+ postEditAjaxRequest({"configvarChange" : 'DISTRO:'+name});
+ $('#distro').text(name);
+ $("#change-distro-form").slideUp(function () {
+ $('#distro, #change-distro-icon').show();
+ });
+ });
+ {% endif %}
+
+ {% if dl_dir_defined %}
+
+ // change DL_DIR variable
+ $('#change-dl_dir-icon').click(function() {
+ $('#change-dl_dir-form').removeClass('has-error');
+ // preset the edit value
+ var current_val = $("#dl_dir").text().trim();
+ if (current_val == "Not set") {
+ current_val="";
+ $("#apply-change-dl_dir").attr("disabled","disabled");
+ }
+ $("input#new-dl_dir").val(current_val);
+ // enable / disable the save button based on the input value
+ if ( current_val.length ) {
+ $("#apply-change-dl_dir").removeAttr("disabled");
+ }
+ else {
+ $("#apply-change-dl_dir").attr("disabled","disabled");
+ }
+
+ $('#change-dl_dir-icon, #dl_dir').hide();
+ $("#change-dl_dir-form").slideDown();
+ });
+
+ $('#cancel-change-dl_dir').click(function(){
+ $("#hintError-dl_dir").hide();
+ $("#hintError-initialChar-dl_dir").hide();
+ $("#change-dl_dir-form").slideUp(function() {
+ $('#dl_dir, #change-dl_dir-icon').show();
+ });
+ });
+
+ $("#new-dl_dir").on('input', function(){
+ if ($(this).val().trim().length == 0) {
+ $("#apply-change-dl_dir").attr("disabled","disabled");
+ $('#change-dl_dir-form').addClass('has-error');
+ $('#hintError-dl_dir').hide();
+ $('#hintError-initialChar-dl_dir').hide();
+ }
+ else {
+ var input = $(this);
+ var reBeginWithSlash = /^\//;
+ var reCheckVariable = /^\$/;
+ var re = /([ <>\\|":\.%\?\*]+)/;
+ var invalidDir = re.test(input.val());
+ var invalidSlash = reBeginWithSlash.test(input.val());
+ var invalidVar = reCheckVariable.test(input.val());
+ if (!invalidSlash && !invalidVar) {
+ $('#change-dl_dir-form').addClass('has-error');
+ $("#apply-change-dl_dir").attr("disabled","disabled");
+ $('#hintError-initialChar-dl_dir').show();
+ } else if (invalidDir) {
+ $('#change-dl_dir-form').addClass('has-error');
+ $("#apply-change-dl_dir").attr("disabled","disabled");
+ $('#hintError-dl_dir').show();
+ } else {
+ $('#change-dl_dir-form').removeClass('has-error');
+ $("#apply-change-dl_dir").removeAttr("disabled");
+ $('#hintError-dl_dir').hide();
+ $('#hintError-initialChar-dl_dir').hide();
+ }
+ }
+ });
+
+ $('#apply-change-dl_dir').click(function(){
+ var value = $('#new-dl_dir').val().trim();
+ postEditAjaxRequest({"configvarChange" : 'DL_DIR:'+value});
+ $('#dl_dir').text(value);
+ $('#dl_dir').removeClass('muted');
+ $("#change-dl_dir-form").slideUp(function () {
+ $('#dl_dir, #change-dl_dir-icon').show();
+ });
+ });
+
+ {% endif %}
+
+ {% if fstypes_defined %}
+ // change IMAGE_FSTYPES variable
+
+ // get value of fstypes and add to the textbox
+ $("#new-imagefs_types").val("{{fstypes}}");
+
+ // If value of new-imagefs_types is empty disable save button
+ $("#new-imagefs_types").on("input", function() {
+ $(this).val($(this).val().replace(/\s+/g,' '));
+ if ($(this).val().length === 0) {
+ //$('#apply-change-image_fstypes').prop('disabled', true);
+ $('#apply-change-image_fstypes').attr("disabled", "disabled");
+ } else {
+ //$('#apply-change-image_fstypes').prop('disabled', false);
+ $('#apply-change-image_fstypes').removeAttr("disabled");
+ }
+
+ /*If user types imagefs do the action on checkboxes.
+ Lets say if an imagefstype typed by user and the same
+ imagefs is unchecked in the checkbox, then checkbox needs
+ to get checked. Similarly when user deletes imagefs from
+ textbox the checkbox which is checked gets unchecked.
+ */
+ $('#all-image_fstypes input').each(function(){
+ var imagefs_userval = $('#new-imagefs_types').val();
+ if( imagefs_userval.indexOf($(this).val()) > -1) {
+ $(this).prop('checked', true);
+ } else {
+ $(this).prop('checked', false);
+ }
+ });
+
+ // Validate underscore in image fs types
+ if ($(this).val().indexOf('_') > -1) {
+ $('#validate-image_fstypes').addClass('has-error');
+ $('#hintError-image-fs_type').show();
+ $("#apply-change-image_fstypes").prop("disabled", true);
+ } else {
+ $('#validate-image_fstypes').removeClass('has-error');
+ $('#hintError-image-fs_type').hide();
+ }
+ });
+
+ $('#change-image_fstypes-icon').click(function() {
+ $('#change-image_fstypes-icon, #image_fstypes').hide();
+ $("#change-image_fstypes-form").slideDown();
+ // avoid false substring matches by including space separators
+ var html = "";
+ var fstypes = " " + document.getElementById("image_fstypes").innerHTML + " ";
+ var fstypes_list = document.getElementsByClassName('js-checkbox-fstypes-list');
+ // Add the checked boxes first
+ if (" " != fstypes) {
+ for (var i = 0, length = fstypes_list.length; i < length; i++) {
+ if (0 <= fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
+ html += '<div class="checkbox"><label><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'" checked="checked">'+fstypes_list[i].value+'</label></div>';
}
-
- $(document).ready(function() {
-
- //
- // Register handlers for static elements
- //
-
- {% if distro_defined %}
- // change distro variable
- $('#change-distro-icon').click(function() {
- $('#change-distro-icon, #distro').hide();
- $("#change-distro-form").slideDown();
- $("#new-distro").val( $('#distro').text() );
- });
-
- $('#cancel-change-distro').click(function(){
- $("#change-distro-form").slideUp(function() {
- $('#distro, #change-distro-icon').show();
-
- // reset any dangling error state
- $('#distro-error-message').text("");
- var d = document.getElementById("edit-distro-name-div");
- d.className = d.className.replace(" error","");
- });
- });
-
- // validate new distro name
- $("input#new-distro").on('input', function (evt) {
- validate_distro_name();
- });
-
- $('#apply-change-distro').click(function(){
- //$('#repo').parent().removeClass('highlight-go');
- var name = $('#new-distro').val();
- postEditAjaxRequest({"configvarChange" : 'DISTRO:'+name});
- $('#distro').text(name);
- $("#change-distro-form").slideUp(function () {
- $('#distro, #change-distro-icon').show();
- });
- });
- {% endif %}
-
- {% if dl_dir_defined %}
-
- // change DL_DIR variable
- $('#change-dl_dir-icon').click(function() {
- $('#hintError-dl_dir').hide();
- // preset the edit value
- var current_val = $("span#dl_dir").text().trim();
- if (current_val == "Not set") {
- current_val="";
- $("#apply-change-dl_dir").attr("disabled","disabled");
- }
- $("input#new-dl_dir").val(current_val);
-
- $('#change-dl_dir-icon, #dl_dir').hide();
- $("#change-dl_dir-form").slideDown();
- });
-
- $('#cancel-change-dl_dir').click(function(){
- $("#change-dl_dir-form").slideUp(function() {
- $('#dl_dir, #change-dl_dir-icon').show();
- });
- });
-
- $("#new-dl_dir").on('input', function(){
- if ($(this).val().trim().length == 0) {
- $("#apply-change-dl_dir").attr("disabled","disabled");
- }
- else {
- var input = $(this);
- var re = /^\/([^ <>\\|":\.%\?\*]+)$/;
- var invalidDir = re.test(input.val());
- console.log(invalidDir);
- if ( invalidDir ) {
- $('#validate-dl_dir').removeClass('control-group error');
- $("#apply-change-dl_dir").removeAttr("disabled");
- $('#hintError-dl_dir').hide();
- } else {
- $('#validate-dl_dir').addClass('control-group error');
- $("#apply-change-dl_dir").attr("disabled","disabled");
- $('#hintError-dl_dir').show();
- }
- }
- });
-
- $('#apply-change-dl_dir').click(function(){
- var value = $('#new-dl_dir').val().trim();
- postEditAjaxRequest({"configvarChange" : 'DL_DIR:'+value});
- $('#dl_dir').text(value);
- $('#dl_dir').removeClass('muted');
- $("#change-dl_dir-form").slideUp(function () {
- $('#dl_dir, #change-dl_dir-icon').show();
- });
- });
-
- {% endif %}
-
- {% if fstypes_defined %}
- // change IMAGE_FSTYPES variable
-
- $('#change-image_fstypes-icon').click(function() {
- $('#change-image_fstypes-icon, #image_fstypes').hide();
- $("#change-image_fstypes-form").slideDown();
- // avoid false substring matches by including space separators
- var html = "";
- var fstypes = " " + document.getElementById("image_fstypes").innerHTML + " ";
- var fstypes_list = document.getElementsByClassName('js-checkbox-fstypes-list');
- // Add the checked boxes first
- if (" " != fstypes) {
- for (var i = 0, length = fstypes_list.length; i < length; i++) {
- if (0 <= fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
- html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'" checked="checked">'+fstypes_list[i].value+'</label>\n';
- }
- }
- }
- // Add the un-checked boxes second
- for (var i = 0, length = fstypes_list.length; i < length; i++) {
- if (0 > fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
- html += '<label class="checkbox"><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'">'+fstypes_list[i].value+'</label>\n';
- }
- }
- // Add the 'no search matches' line last
- html += '<label id="no-match-fstypes">No image types found</label>\n';
- // Display the list
- document.getElementById("all-image_fstypes").innerHTML = html;
- $('#no-match-fstypes').hide();
-
- // Watch elements to disable Save when none are checked
- $(".fs-checkbox-fstypes").each(function(){
- $(this).click(function() {
- enableFsTypesSave();
- });
- });
-
- // clear the previous filter values and warning messages
- $("input#filter-image_fstypes").val("");
- $('#fstypes-error-message').hide();
- });
-
- $('#cancel-change-image_fstypes').click(function(){
- $("#change-image_fstypes-form").slideUp(function() {
- $('#image_fstypes, #change-image_fstypes-icon').show();
- });
- });
-
- $('#filter-image_fstypes').on('input', function(){
- var valThis = $(this).val().toLowerCase();
- var matchCount=0;
- $('#all-image_fstypes label').each(function(){
- var text = $(this).text().toLowerCase();
- var match = text.indexOf(valThis);
- if (match >= 0) {
- $(this).show();
- matchCount += 1;
- }
- else {
- $(this).hide();
- }
- });
- if (matchCount === 0) {
- $('#no-match-fstypes').show();
- } else {
- $('#no-match-fstypes').hide();
- }
- });
-
- $('#apply-change-image_fstypes').click(function(){
- // extract the selected fstypes and sort them
- var fstypes_array = [];
- var checkboxes = document.getElementsByClassName('fs-checkbox-fstypes');
- $(".fs-checkbox-fstypes:checked").each(function(){
- fstypes_array.push($(this).val());
- });
- fstypes_array.sort();
-
- // now make a string of them
- var fstypes = '';
- for (var i = 0, length = fstypes_array.length; i < length; i++) {
- fstypes += fstypes_array[i] + ' ';
- }
- fstypes = fstypes.trim();
-
- postEditAjaxRequest({"configvarChange" : 'IMAGE_FSTYPES:'+fstypes});
- $('#image_fstypes').text(fstypes);
- $('#image_fstypes').parent().removeClass('muted');
-
- $("#change-image_fstypes-form").slideUp(function() {
- $('#image_fstypes, #change-image_fstypes-icon').show();
- });
- });
- {% endif %}
-
-
- {% if image_install_append_defined %}
-
- // init IMAGE_INSTALL_append trash icon
- setDeleteTooltip($('#delete-image_install-icon'));
-
- // change IMAGE_INSTALL_append variable
- $('#change-image_install-icon').click(function() {
- // preset the edit value
- var current_val = $("span#image_install").text().trim();
- if (current_val == "Not set") {
- current_val="";
- $("#apply-change-image_install").attr("disabled","disabled");
- } else {
- // insure these non-empty values have single space prefix
- current_val=" " + current_val;
- }
- $("input#new-image_install").val(current_val);
-
- $('#change-image_install-icon, #delete-image_install-icon, #image_install').hide();
- $("#change-image_install-form").slideDown();
- });
-
- $('#cancel-change-image_install').click(function(){
- $("#change-image_install-form").slideUp(function() {
- $('#image_install, #change-image_install-icon').show();
- if ($("span#image_install").text() != "Not set") {
- $('#delete-image_install-icon').show();
- setDeleteTooltip($('#delete-image_install-icon'));
- }
- });
- });
-
- $("#new-image_install").on('input', function(){
- if ($(this).val().trim().length == 0) {
- $("#apply-change-image_install").attr("disabled","disabled");
- }
- else {
- $("#apply-change-image_install").removeAttr("disabled");
- }
- });
-
- $('#apply-change-image_install').click(function(){
- // insure these non-empty values have single space prefix
- var value = " " + $('#new-image_install').val().trim();
- postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+value});
- $('#image_install').text(value);
- $('#image_install').removeClass('muted');
- $("#change-image_install-form").slideUp(function () {
- $('#image_install, #change-image_install-icon').show();
- if (value.length > -1) {
- $('#delete-image_install-icon').show();
- setDeleteTooltip($('#delete-image_install-icon'));
- }
- });
- });
-
- // delete IMAGE_INSTALL_append variable value
- $('#delete-image_install-icon').click(function(){
- $(this).tooltip('hide');
- postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+''});
- $('#image_install').parent().fadeOut(1000, function(){
- $('#image_install').addClass('muted');
- $('#image_install').text('Not set');
- $('#delete-image_install-icon').hide();
- $('#image_install').parent().fadeIn(1000);
- });
- });
- {% endif %}
-
-
- {% if package_classes_defined %}
- // change PACKAGE_CLASSES variable
- $('#change-package_classes-icon').click(function() {
- $('#change-package_classes-icon, #package_classes').hide();
- $("#change-package_classes-form").slideDown();
-
- // initialize the pulldown and checkboxes
- var value = $("#package_classes").text();
- if ( value.indexOf("package_deb") == 0 ) {
- $("#package_classes-select").prop('selectedIndex', 0);
- updatePackageClassCheckboxes();
- if ( value.indexOf("_ipk") > 0 ) {
- $("#package_class_1_input").attr("checked",true);
- }
- if ( value.indexOf("_rpm") > 0 ) {
- $("#package_class_2_input").attr("checked",true);
- }
- }
-
- if ( value.indexOf("package_ipk") == 0 ) {
- $("#package_classes-select").prop('selectedIndex', 1);
- updatePackageClassCheckboxes();
- if ( value.indexOf("_deb") > 0 ) {
- $("#package_class_1_input").attr("checked",true);
- }
- if ( value.indexOf("_rpm") > 0 ) {
- $("#package_class_2_input").attr("checked",true);
- }
- }
-
- if ( value.indexOf("package_rpm") == 0 ) {
- $("#package_classes-select").prop('selectedIndex', 2);
- updatePackageClassCheckboxes();
- if ( value.indexOf("_deb") > 0 ) {
- $("#package_class_1_input").attr("checked",true);
- }
- if ( value.indexOf("_ipk") > 0 ) {
- $("#package_class_2_input").attr("checked",true);
- }
- }
- });
-
- $('#cancel-change-package_classes').click(function(){
- $("#change-package_classes-form").slideUp(function() {
- $('#package_classes, #change-package_classes-icon').show();
- });
- });
-
- $('select').change(function() {
- updatePackageClassCheckboxes();
- });
-
- $('#apply-change-package_classes').click(function(){
- var e = document.getElementById("package_classes-select");
- var val = e.options[e.selectedIndex].text;
-
- pc1_checked = document.getElementById("package_class_1_input").checked;
- pc2_checked = document.getElementById("package_class_2_input").checked;
- if (val == "package_deb") {
- if (pc1_checked) val = val + " package_ipk";
- if (pc2_checked) val = val + " package_rpm";
- }
- if (val == "package_ipk") {
- if (pc1_checked) val = val + " package_deb";
- if (pc2_checked) val = val + " package_rpm";
- }
- if (val == "package_rpm") {
- if (pc1_checked) val = val + " package_deb";
- if (pc2_checked) val = val + " package_ipk";
- }
-
- $('#package_classes').text(val);
- //$('#package_classes').parent().removeClass('muted');
- postEditAjaxRequest({"configvarChange" : 'PACKAGE_CLASSES:'+val});
- $("#change-package_classes-form").slideUp(function() {
- $('#package_classes, #change-package_classes-icon').show();
- });
- });
- {% endif %}
-
- {% if sstate_dir_defined %}
-
- // change SSTATE_DIR variable
- $('#change-sstate_dir-icon').click(function() {
- $('#hintError-sstate_dir').hide();
- // preset the edit value
- var current_val = $("span#sstate_dir").text().trim();
- if (current_val == "Not set") {
- current_val="";
- $("#apply-change-sstate_dir").attr("disabled","disabled");
- }
- $("input#new-sstate_dir").val(current_val);
-
- $('#change-sstate_dir-icon, #sstate_dir').hide();
- $("#change-sstate_dir-form").slideDown();
- });
-
- $('#cancel-change-sstate_dir').click(function(){
- $("#change-sstate_dir-form").slideUp(function() {
- $('#sstate_dir, #change-sstate_dir-icon').show();
- });
- });
-
- $("#new-sstate_dir").on('input', function(){
- if ($(this).val().trim().length == 0) {
- $("#apply-change-sstate_dir").attr("disabled","disabled");
- }
- else {
- var input = $(this);
- var re = /^\/([^ <>\\|":\.%\?\*]+)$/;
- var invalidDir = re.test(input.val());
- console.log(invalidDir);
- if ( invalidDir ) {
- $('#validate-sstate_dir').removeClass('control-group error');
- $("#apply-change-sstate_dir").removeAttr("disabled");
- $('#hintError-sstate_dir').hide();
- } else {
- $('#validate-sstate_dir').addClass('control-group error');
- $("#apply-change-sstate_dir").attr("disabled","disabled");
- $('#hintError-sstate_dir').show();
- }
- }
- });
-
- $('#apply-change-sstate_dir').click(function(){
- var value = $('#new-sstate_dir').val().trim();
- postEditAjaxRequest({"configvarChange" : 'SSTATE_DIR:'+value});
- $('#sstate_dir').text(value);
- $('#sstate_dir').removeClass('muted');
- $("#change-sstate_dir-form").slideUp(function () {
- $('#sstate_dir, #change-sstate_dir-icon').show();
- });
- });
-
- {% endif %}
-
- // add new variable
- $("button#add-configvar-button").click( function (evt) {
- var variable = $("input#variable").val();
- var value = $("input#value").val();
-
- postEditAjaxRequest({"configvarAdd" : variable+':'+value});
-
- // clear the previous values
- $("input#variable").val("");
- $("input#value").val("");
- // Disable add button
- $(".save").attr("disabled","disabled");
-
- // Reload page if admin-removed core managed value is manually added back in
- if (0 <= " DISTRO DL_DIR IMAGE_FSTYPES IMAGE_INSTALL_append PACKAGE_CLASSES SSTATE_DIR ".indexOf( " "+variable+" " )) {
- // delayed reload to avoid race condition with postEditAjaxRequest
- do_reload=true;
- }
- });
-
- // validate new variable name and value
- $("#variable, #value").on('input', function() {
- validate_new_variable();
- });
-
- //
- // draw and register the dynamic configuration variables and handlers
- //
-
- var data = {
- configvars : []
- };
- {% for c in configvars %}
- data.configvars.push([ "{{c.name}}","{{c.value}}","{{c.pk}}" ]);
- {% if '' != vars_context|get_dict_value:c.name %}
- data.vars_context[ "{{c.name}}" ] = "{{vars_context|get_dict_value:c.name }}";
- {% endif %}
- {% endfor %}
-
- // draw these elements and assert their event handlers
- onEditPageUpdate(data);
- });
-
- </script>
+ }
+ }
+ // Add the un-checked boxes second
+ for (var i = 0, length = fstypes_list.length; i < length; i++) {
+ if (0 > fstypes.indexOf(" "+fstypes_list[i].value+" ")) {
+ html += '<div class="checkbox"><label><input type="checkbox" class="fs-checkbox-fstypes" value="'+fstypes_list[i].value+'">'+fstypes_list[i].value+'</label></div>';
+ }
+ }
+ // Add the 'no search matches' line last
+ html += '<label id="no-match-fstypes" class="text-muted">No image types found</label>\n';
+ // Display the list
+ document.getElementById("all-image_fstypes").innerHTML = html;
+ $('#no-match-fstypes').hide();
+
+ // clear the previous filter values and warning messages
+ $("input#filter-image_fstypes").val("");
+ });
+
+ // When checkbox is checked/unchecked kindly update the text
+ $(document).on("change", "#all-image_fstypes :checkbox", function() {
+ var imagefs = $(this);
+ var imagefs_obj = $('#new-imagefs_types');
+ var imagefs_userval = imagefs_obj.val();
+ if ($(this).is(':checked')) {
+ if (imagefs_userval.indexOf($(imagefs).val()) === -1) {
+ imagefs_obj.val(imagefs_userval + " " + $(imagefs).val());
+ }
+ } else {
+ if (imagefs_userval.indexOf($(imagefs).val()) > -1) {
+ imagefs_obj.val(imagefs_userval.replace($(imagefs).val(), '').trim());
+ }
+ }
+ if ($('#new-imagefs_types').val().length === 0) {
+ $("#apply-change-image_fstypes").prop("disabled", true);
+ } else {
+ $("#apply-change-image_fstypes").prop("disabled", false);
+ }
+ });
+
+ $('#cancel-change-image_fstypes').click(function(){
+ $("#new-imagefs_types").val("{{fstypes}}");
+ $("#change-image_fstypes-form").slideUp(function() {
+ $('#image_fstypes, #change-image_fstypes-icon').show();
+ });
+ });
+
+ $('#filter-image_fstypes').on('input', function(){
+ var valThis = $(this).val().toLowerCase();
+ var matchCount=0;
+ $('#all-image_fstypes label').each(function(){
+ var text = $(this).text().toLowerCase();
+ var match = text.indexOf(valThis);
+ if (match >= 0) {
+ $(this).show();
+ matchCount += 1;
+ }
+ else {
+ $(this).hide();
+ }
+ });
+ if (matchCount === 0) {
+ $('#no-match-fstypes').show();
+ } else {
+ $('#no-match-fstypes').hide();
+ }
+ });
+
+ $('#apply-change-image_fstypes').click(function(){
+ var fstypes = $('#new-imagefs_types').val();
+
+ postEditAjaxRequest({"configvarChange" : 'IMAGE_FSTYPES:'+fstypes});
+ $('#image_fstypes').text(fstypes);
+ $('#image_fstypes').parent().removeClass('muted');
+
+ $("#change-image_fstypes-form").slideUp(function() {
+ $('#image_fstypes, #change-image_fstypes-icon').show();
+ });
+ });
+ {% endif %}
+
+
+ {% if image_install_append_defined %}
+
+ // init IMAGE_INSTALL_append trash icon
+ setDeleteTooltip($('#delete-image_install-icon'));
+
+ // change IMAGE_INSTALL_append variable
+ $('#change-image_install-icon').click(function() {
+ // preset the edit value
+ var current_val = $("span#image_install").text().trim();
+ if (current_val == "Not set") {
+ current_val="";
+ $("#apply-change-image_install").attr("disabled","disabled");
+ } else {
+ // insure these non-empty values have single space prefix
+ current_val=" " + current_val;
+ $("#apply-change-image_install").removeAttr("disabled");
+ }
+ $("input#new-image_install").val(current_val);
+
+ $('#change-image_install-icon, #delete-image_install-icon, #image_install').hide();
+ $("#change-image_install-form").slideDown();
+ });
+
+ $('#cancel-change-image_install').click(function(){
+ $("#change-image_install-form").slideUp(function() {
+ $('#image_install, #change-image_install-icon').show();
+ if ($("span#image_install").text() != "Not set") {
+ $('#delete-image_install-icon').show();
+ setDeleteTooltip($('#delete-image_install-icon'));
+ }
+ });
+ });
+
+ $("#new-image_install").on('input', function(){
+ if ($(this).val().trim().length == 0) {
+ $("#apply-change-image_install").attr("disabled","disabled");
+ }
+ else {
+ $("#apply-change-image_install").removeAttr("disabled");
+ }
+ });
+
+ $('#apply-change-image_install').click(function(){
+ // insure these non-empty values have single space prefix
+ var value = " " + $('#new-image_install').val().trim();
+ postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+value});
+ $('#image_install').text(value);
+ $('#image_install').removeClass('text-muted');
+ $("#change-image_install-form").slideUp(function () {
+ $('#image_install, #change-image_install-icon').show();
+ if (value.length > -1) {
+ $('#delete-image_install-icon').show();
+ setDeleteTooltip($('#delete-image_install-icon'));
+ }
+ });
+ });
+
+ // delete IMAGE_INSTALL_append variable value
+ $('#delete-image_install-icon').click(function(){
+ $(this).tooltip('hide');
+ postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+''});
+ $('#image_install').parent().fadeOut(1000, function(){
+ $('#image_install').addClass('text-muted');
+ $('#image_install').text('Not set');
+ $('#delete-image_install-icon').hide();
+ $('#image_install').parent().fadeIn(1000);
+ });
+ });
+ {% endif %}
+
+
+ {% if package_classes_defined %}
+ // change PACKAGE_CLASSES variable
+ $('#change-package_classes-icon').click(function() {
+ $('#change-package_classes-icon, #package_classes').hide();
+ $("#change-package_classes-form").slideDown();
+
+ // initialize the pulldown and checkboxes
+ var value = $("#package_classes").text();
+ if ( value.indexOf("package_deb") == 0 ) {
+ $("#package_classes-select").prop('selectedIndex', 0);
+ updatePackageClassCheckboxes();
+ if ( value.indexOf("_ipk") > 0 ) {
+ $("#package_class_1_input").attr("checked",true);
+ }
+ if ( value.indexOf("_rpm") > 0 ) {
+ $("#package_class_2_input").attr("checked",true);
+ }
+ }
+
+ if ( value.indexOf("package_ipk") == 0 ) {
+ $("#package_classes-select").prop('selectedIndex', 1);
+ updatePackageClassCheckboxes();
+ if ( value.indexOf("_deb") > 0 ) {
+ $("#package_class_1_input").attr("checked",true);
+ }
+ if ( value.indexOf("_rpm") > 0 ) {
+ $("#package_class_2_input").attr("checked",true);
+ }
+ }
+
+ if ( value.indexOf("package_rpm") == 0 ) {
+ $("#package_classes-select").prop('selectedIndex', 2);
+ updatePackageClassCheckboxes();
+ if ( value.indexOf("_deb") > 0 ) {
+ $("#package_class_1_input").attr("checked",true);
+ }
+ if ( value.indexOf("_ipk") > 0 ) {
+ $("#package_class_2_input").attr("checked",true);
+ }
+ }
+ });
+
+ $('#cancel-change-package_classes').click(function(){
+ $("#change-package_classes-form").slideUp(function() {
+ $('#package_classes, #change-package_classes-icon').show();
+ });
+ });
+
+ $('select').change(function() {
+ updatePackageClassCheckboxes();
+ });
+
+ $('#apply-change-package_classes').click(function(){
+ var e = document.getElementById("package_classes-select");
+ var val = e.options[e.selectedIndex].text;
+
+ pc1_checked = document.getElementById("package_class_1_input").checked;
+ pc2_checked = document.getElementById("package_class_2_input").checked;
+ if (val == "package_deb") {
+ if (pc1_checked) val = val + " package_ipk";
+ if (pc2_checked) val = val + " package_rpm";
+ }
+ if (val == "package_ipk") {
+ if (pc1_checked) val = val + " package_deb";
+ if (pc2_checked) val = val + " package_rpm";
+ }
+ if (val == "package_rpm") {
+ if (pc1_checked) val = val + " package_deb";
+ if (pc2_checked) val = val + " package_ipk";
+ }
+
+ $('#package_classes').text(val);
+ //$('#package_classes').parent().removeClass('muted');
+ postEditAjaxRequest({"configvarChange" : 'PACKAGE_CLASSES:'+val});
+ $("#change-package_classes-form").slideUp(function() {
+ $('#package_classes, #change-package_classes-icon').show();
+ });
+ });
+ {% endif %}
+
+ {% if sstate_dir_defined %}
+
+ // change SSTATE_DIR variable
+ $('#change-sstate_dir-icon').click(function() {
+ $('#change-sstate_dir-form').removeClass('has-error');
+ // preset the edit value
+ var current_val = $("span#sstate_dir").text().trim();
+ if (current_val == "Not set") {
+ current_val="";
+ $("#apply-change-sstate_dir").attr("disabled","disabled");
+ }
+ $("input#new-sstate_dir").val(current_val);
+
+ // enable / disable the save button based on the input value
+ if ( current_val.length ) {
+ $("#apply-change-sstate_dir").removeAttr("disabled");
+ }
+ else {
+ $("#apply-change-sstate_dir").attr("disabled","disabled");
+ }
+
+ $('#change-sstate_dir-icon, #sstate_dir').hide();
+ $("#change-sstate_dir-form").slideDown();
+ });
+
+ $('#cancel-change-sstate_dir').click(function(){
+ $("#hintError-sstate_dir").hide();
+ $("#hintError-initialChar-sstate_dir").hide();
+ $("#change-sstate_dir-form").slideUp(function() {
+ $('#sstate_dir, #change-sstate_dir-icon').show();
+ });
+ });
+
+ $("#new-sstate_dir").on('input', function(){
+ if ($(this).val().trim().length == 0) {
+ $("#apply-change-sstate_dir").attr("disabled","disabled");
+ $('#change-sstate_dir-form').addClass('has-error');
+ $('#hintError-sstate_dir').hide();
+ $('#hintError-initialChar-sstate_dir').hide();
+ }
+ else {
+ var input = $(this);
+ var reBeginWithSlash = /^\//;
+ var reCheckVariable = /^\$/;
+ var re = /([ <>\\|":\.%\?\*]+)/;
+ var invalidDir = re.test(input.val());
+ var invalidSlash = reBeginWithSlash.test(input.val());
+ var invalidVar = reCheckVariable.test(input.val());
+ if (!invalidSlash && !invalidVar) {
+ $('#change-sstate_dir-form').addClass('has-error');
+ $("#apply-change-sstate_dir").attr("disabled","disabled");
+ $('#hintError-initialChar-sstate_dir').show();
+ } else if (invalidDir) {
+ $('#change-sstate_dir-form').addClass('has-error');
+ $("#apply-change-sstate_dir").attr("disabled","disabled");
+ $('#hintError-sstate_dir').show();
+ } else {
+ $('#change-sstate_dir-form').removeClass('has-error');
+ $("#apply-change-sstate_dir").removeAttr("disabled");
+ $('#hintError-sstate_dir').hide();
+ $('#hintError-initialChar-sstate_dir').hide();
+ }
+ }
+ });
+
+ $('#apply-change-sstate_dir').click(function(){
+ var value = $('#new-sstate_dir').val().trim();
+ postEditAjaxRequest({"configvarChange" : 'SSTATE_DIR:'+value});
+ $('#sstate_dir').text(value);
+ $('#sstate_dir').removeClass('text-muted');
+ $("#change-sstate_dir-form").slideUp(function () {
+ $('#sstate_dir, #change-sstate_dir-icon').show();
+ });
+ });
+
+ {% endif %}
+
+ // add new variable
+ $("button#add-configvar-button").click( function (evt) {
+ var variable = $("input#variable").val();
+ var value = $("input#value").val();
+
+ postEditAjaxRequest({"configvarAdd" : variable+':'+value});
+
+ // clear the previous values
+ $("input#variable").val("");
+ $("input#value").val("");
+ // Disable add button
+ $(".save").attr("disabled","disabled");
+
+ // Reload page if admin-removed core managed value is manually added back in
+ if (0 <= " DISTRO DL_DIR IMAGE_FSTYPES IMAGE_INSTALL_append PACKAGE_CLASSES SSTATE_DIR ".indexOf( " "+variable+" " )) {
+ // delayed reload to avoid race condition with postEditAjaxRequest
+ do_reload=true;
+ }
+ });
+
+ // validate new variable name and value
+ $("#variable, #value").on('input', function() {
+ validate_new_variable();
+ });
+
+ //
+ // draw and register the dynamic configuration variables and handlers
+ //
+
+ var data = {
+ configvars : []
+ };
+ {% for c in configvars %}
+ data.configvars.push([ "{{c.name}}","{{c.value}}","{{c.pk}}" ]);
+ {% if '' != vars_context|get_dict_value:c.name %}
+ data.vars_context[ "{{c.name}}" ] = "{{vars_context|get_dict_value:c.name }}";
+ {% endif %}
+ {% endfor %}
+
+ // draw these elements and assert their event handlers
+ onEditPageUpdate(data);
+});
+
+</script>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projects-toastertable.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projects-toastertable.html
index 5814f32d0..d8020a97f 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projects-toastertable.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projects-toastertable.html
@@ -4,33 +4,39 @@
{% block pagecontent %}
- <div class="page-header top-air">
- <h1 data-role="page-title"></h1>
- </div>
-
- {% url 'projects' as xhr_table_url %}
- {% include 'toastertable.html' %}
-
- <script>
- $(document).ready(function () {
- var tableElt = $("#{{table_name}}");
- var titleElt = $("[data-role='page-title']");
-
- tableElt.on("table-done", function (e, total, tableParams) {
- var title = "All projects";
-
- if (tableParams.search || tableParams.filter) {
- if (total === 0) {
- title = "No projects found";
- }
- else if (total > 0) {
- title = total + " project" + (total > 1 ? 's' : '') + " found";
- }
- }
-
- titleElt.text(title);
+<div class="row">
+ <div class="col-md-12">
+
+ <div class="page-header">
+ <h1 data-role="page-title"></h1>
+ </div>
+
+ {% url 'projects' as xhr_table_url %}
+ {% include 'toastertable.html' %}
+
+ <script>
+$(document).ready(function () {
+ var tableElt = $("#{{table_name}}");
+ var titleElt = $("[data-role='page-title']");
+
+ tableElt.on("table-done", function (e, total, tableParams) {
+ var title = "All projects";
+
+ if (tableParams.search || tableParams.filter) {
+ if (total === 0) {
+ title = "No projects found";
+ }
+ else if (total > 0) {
+ title = total + " project" + (total > 1 ? 's' : '') + " found";
+ }
+ }
+
+ titleElt.text(title);
});
});
- </script>
+ </script>
+
+ </div>
+</div>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projecttopbar.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projecttopbar.html
index 007de06ff..768ca9455 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projecttopbar.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/projecttopbar.html
@@ -16,63 +16,64 @@
});
</script>
-<div class="alert alert-success lead" id="project-created-notification" style="margin-top:15px; display:none">
- <button type="button" class="close" data-dismiss="alert">Ă—</button>
- Your project <strong>{{project.name}}</strong> has been created. You can now <a href="{% url 'projectmachines' project.id %}">select your target machine</a> and <a href="{% url 'projectimagerecipes' project.id %}">choose image recipes</a> to build.
-</div>
-
-<!-- project name -->
-<div class="page-header">
- <h1 id="project-name-container">
- <span id="project-name">{{project.name}}</span>
+<div class="col-md-12">
+ <div class="alert alert-success alert-dismissible change-notification" id="project-created-notification" style="display:none">
+ <button type="button" class="close" data-dismiss="alert">&times;</button>
+ <p>Your project <strong>{{project.name}}</strong> has been created. You can now <a class="alert-link" href="{% url 'projectmachines' project.id %}">select your target machine</a> and <a class="alert-link" href="{% url 'projectimagerecipes' project.id %}">choose image recipes</a> to build.</p>
+ </div>
+ <!-- project name -->
+ <div class="page-header">
+ <h1 id="project-name-container">
+ <span class="project-name">{{project.name}}</span>
- <i class="icon-pencil" data-original-title="" id="project-change-form-toggle" title=""></i>
+ <span class="glyphicon glyphicon-edit" id="project-change-form-toggle"></i>
- {% if project.is_default %}
- <i class="icon-question-sign get-help heading-help" title="" data-original-title="This project shows information about the builds you start from the command line while Toaster is running"></i>
- {% endif %}
- </h1>
- <form id="project-name-change-form" style="margin-bottom: 0px; display: none;">
- <div class="input-append">
- <input class="huge input-xxlarge" type="text" id="project-name-change-input" autocomplete="off" value="{{project.name}}">
- <button id="project-name-change-btn" class="btn btn-large" type="button">Save</button>
- <a href="#" id="project-name-change-cancel" class="btn btn-large btn-link">Cancel</a>
- </div>
- </form>
-</div>
+ {% if project.is_default %}
+ <span class="glyphicon glyphicon-question-sign get-help" title="This project shows information about the builds you start from the command line while Toaster is running"></span>
+ {% endif %}
+ </h1>
+ <form id="project-name-change-form" class="form-inline" style="display: none;">
+ <div class="form-group">
+ <input class="form-control input-lg" type="text" id="project-name-change-input" autocomplete="off" value="{{project.name}}">
+ </div>
+ <button id="project-name-change-btn" class="btn btn-default btn-lg" type="button">Save</button>
+ <a href="#" id="project-name-change-cancel" class="btn btn-lg btn-link">Cancel</a>
+ </form>
+ </div>
-{% if not project.is_default %}
+ {% if not project.is_default %}
<div id="project-topbar">
- <ul class="nav nav-pills">
+ <ul class="nav nav-tabs">
<li id="topbar-configuration-tab">
- <a href="{% url 'project' project.id %}">
- Configuration
- </a>
+ <a href="{% url 'project' project.id %}">
+ Configuration
+ </a>
</li>
<li>
- <a href="{% url 'projectbuilds' project.id %}">
- Builds ({{project.get_number_of_builds}})
- </a>
+ <a href="{% url 'projectbuilds' project.id %}">
+ Builds ({{project.get_number_of_builds}})
+ </a>
</li>
<li>
- <a href="{% url 'importlayer' project.id %}">
- Import layer
- </a>
+ <a href="{% url 'importlayer' project.id %}">
+ Import layer
+ </a>
</li>
<li>
- <a href="{% url 'newcustomimage' project.id %}">
- New custom image
- </a>
+ <a href="{% url 'newcustomimage' project.id %}">
+ New custom image
+ </a>
</li>
<li class="pull-right">
- <form class="form-inline" style="margin-bottom:0px;">
- <i class="icon-question-sign get-help heading-help" data-placement="left" title="" data-original-title="Type the name of one or more recipes you want to build, separated by a space. You can also specify a task by appending a colon and a task name to the recipe name, like so: <code>busybox:clean</code>"></i>
- <div class="input-append">
- <input id="build-input" type="text" class="input-xlarge input-lg build-target-input" placeholder="Type the recipe you want to build" autocomplete="off" disabled>
- <button id="build-button" class="btn btn-primary btn-large build-button" data-project-id="{{project.id}}" disabled>Build</button>
+ <form class="form-inline">
+ <div class="form-group">
+ <span class="glyphicon glyphicon-question-sign get-help" data-placement="left" title="Type the name of one or more recipes you want to build, separated by a space. You can also specify a task by appending a colon and a task name to the recipe name, like so: <code>busybox:clean</code>"></span>
+ <input id="build-input" type="text" class="form-control input-lg" placeholder="Type the recipe you want to build" autocomplete="off" disabled>
</div>
+ <button id="build-button" class="btn btn-primary btn-lg" data-project-id="{{project.id}}" disabled>Build</button>
</form>
</li>
</ul>
</div>
-{% endif %}
+ {% endif %}
+</div>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe.html
index 1d6d64e3c..bf2cd7169 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe.html
@@ -12,35 +12,43 @@
<!-- Begin container -->
-<div class="row span11">
- <div class="page-header">
+<div class="row">
+ <div class="col-md-12">
+ <div class="page-header build-data">
<h1>{{object.name}}_{{object.version}}</h1>
</div>
+ </div>
</div>
-<div class="row span7 tabbable">
- <ul class="nav nav-pills">
+<div class="row">
+ <div class="col-md-8 tabbable">
+ <ul class="nav nav-tabs">
<li class="{{tab_states.1}}">
<a href="#information" data-toggle="tab">
- <i class="icon-question-sign get-help" title="Build-related information about the recipe"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Build-related
+ information about the recipe"></span>
Recipe details
</a>
</li>
<li>
<a href="{% url "recipe_packages" build.pk object.id %}">
- <i class="icon-question-sign get-help" title="The packaged output resulting from building the recipe"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The packaged
+ output resulting from building the recipe"></span>
Packages ({{package_count}})
</a>
</li>
<li class="{{tab_states.3}}">
<a href="#dependencies" data-toggle="tab">
- <i class="icon-question-sign get-help" title="The recipe build-time dependencies (i.e. other recipes)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The recipe
+ build-time dependencies (i.e. other recipes)"></span>
Build dependencies ({{object.r_dependencies_recipe.all.count}})
</a>
</li>
<li class="{{tab_states.4}}">
<a href="#brought-in-by" data-toggle="tab">
- <i class="icon-question-sign get-help" title="The recipe build-time reverse dependencies (i.e. the recipes that depend on this recipe)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The recipe
+ build-time reverse dependencies (i.e. the recipes that
+ depend on this recipe)"></span>
Reverse build dependencies ({{object.r_dependencies_depends.all.count}})
</a>
</li>
@@ -49,34 +57,55 @@
<div class="tab-pane {{tab_states.1}}" id="information">
<dl class="dl-horizontal">
<dt>
- <i class="icon-question-sign get-help" title="The name of the layer providing the recipe"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The name of
+ the layer providing the recipe"></span>
Layer
</dt>
<dd>{{layer.name}}</dd>
<dt>
- <i class="icon-question-sign get-help" title="Path to the recipe .bb file"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Path to the
+ recipe .bb file"></span>
Recipe file
</dt>
<dd><code>{{object.file_path}} {% if object.pathflags %}<i>({{object.pathflags}})</i>{% endif %}</code></dd>
- {% if layer_version.branch %}
<dt>
- <i class="icon-question-sign get-help" title="The Git branch of the layer providing the recipe"></i>
+ <span class="glyphicon glyphicon-question-sign get-help"
+ title="The Git branch of the layer providing the
+ recipe"></span>
Layer branch
</dt>
+ {% if layer_version.layer.local_source_dir %}
+ <dd>
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The source
+ code of {{layer_version.layer.name}} is not in a git repository
+ so there is no branch associated with it"></span>
+ </dd>
+ {% else %}
<dd>{{layer_version.branch}}</dd>
- {% endif %}
+ {% endif %}
<dt>
- <i class="icon-question-sign get-help" title="The Git commit of the layer providing the recipe"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The Git
+ commit of the layer providing the recipe"></span>
Layer commit
</dt>
+ {% if layer_version.layer.local_source_dir %}
+ <dd>
+ <span class="text-muted">Not applicable</span>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The source
+ code of {{layer_version.layer.name}} is not in a git repository
+ so there is no commit associated with it"></span>
+ </dd>
+ {% else %}
<dd class="iscommit">{{layer_version.commit}}</dd>
+ {% endif %}
{% if object.provides_set.all %}
<dt>
- <i class="icon-question-sign get-help"
+ <span class="glyphicon glyphicon-question-sign get-help"
title="A list of aliases by which a particular recipe can be known. The additional aliases are
synonyms for the recipe and can be useful satisfying dependencies of other recipes during
- the build"></i>
+ the build"></span>
PROVIDES
</dt>
<dd><code>{% for provider in object.provides_set.all %}{{ provider.name }}&nbsp;{% endfor %}</code></dd>
@@ -89,30 +118,45 @@
<strong>{{object.name}}_{{object.version}}</strong> does not have any tasks in this build.
</div>
{% else %}
+ <div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
- <tr>
+ <tr>
<th>
- <i class="icon-question-sign get-help" title="The running sequence of each task in the build"></i>
+ <span class="glyphicon glyphicon-question-sign
+ get-help" title="The running sequence of each task
+ in the build"></span>
Order
</th>
<th>
- <i class="icon-question-sign get-help" title="The name of the task"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The name
+ of the task"></span>
Task
</th>
<th>
- <i class="icon-question-sign get-help" title="This value tells you if a task had to run (executed) in order to generate the task output, or if the output was provided by another task and therefore the task didn't need to run (not executed)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="This
+ value tells you if a task had to run (executed) in
+ order to generate the task output, or if the output was
+ provided by another task and therefore the task didn't need
+ to run (not executed)"></span>
Executed
</th>
<th>
- <i class="icon-question-sign get-help" title="This column tells you if 'executed' tasks succeeded or failed. The column also tells you why 'not executed' tasks did not need to run"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="This
+ column tells you if 'executed' tasks succeeded or
+ failed. The column also tells you why 'not executed'
+ tasks did not need to run"></span>
Outcome
</th>
<th>
- <i class="icon-question-sign get-help" title="This column tells you if a task tried to restore output from the <code>sstate-cache</code> directory or mirrors, and reports the result: Succeeded, Failed or File not in cache"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="This
+ column tells you if a task tried to restore output
+ from the <code>sstate-cache</code> directory or
+ mirrors, and reports the result: Succeeded, Failed or File
+ not in cache"></span>
Cache attempt
</th>
- </tr>
+ </tr>
</thead>
<tbody>
@@ -120,26 +164,30 @@
<tr {{ task|task_color }} >
- <td><a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.order}}</a></td>
+ <td>{{task.order}}</td>
<td>
- <a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.task_name}}</a>
- {% if task.get_description %}<i class="icon-question-sign get-help hover-help" title="" data-original-title="{{task.get_description}}"></i> {% endif %}
+ <a href="{% url "task" build.pk task.pk %}">{{task.task_name}}</a>
+ {% if task.get_description %}<span class="glyphicon
+ glyphicon-question-sign get-help hover-help"
+ title="{{task.get_description}}"></span>
+ {% endif %}
</td>
- <td><a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.get_executed_display}}</a></td>
+ <td>{{task.get_executed_display}}</td>
- <td>
- <a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.get_outcome_display}} </a>
+ <td>{{task.get_outcome_display}}
{% if task.outcome = task.OUTCOME_FAILED %}
<a href="{% url 'build_artifact' build.pk "tasklogfile" task.pk %}">
- <i class="icon-download-alt" title="Download task log file"></i>
+ <span class="glyphicon glyphicon-download-alt
+ get-help" title="Download task log
+ file"></span>
</a>
{% endif %}
<i class="icon-question-sign get-help hover-help" title="{{task.get_outcome_help}}"></i>
</td>
<td>
{% ifnotequal task.sstate_result task.SSTATE_NA %}
- <a {{ task|task_color }} href="{% url "task" build.pk task.pk %}">{{task.get_sstate_result_display}}</a>
+ {{task.get_sstate_result_display}}
{% endifnotequal %}
</td>
@@ -148,6 +196,7 @@
{% endfor %}
</tbody>
</table>
+ </div>
{% endif %}
</div>
<div class="tab-pane {{tab_states.3}}" id="dependencies">
@@ -174,13 +223,13 @@
<tr>
<td><a href="{% url "recipe" build.pk rr.depends_on.pk %}">{{rr.depends_on.name}}</a>
{% if rr.via %}
- <span class="muted">satisfied via {{rr.via.name}}</span>
- <i class="icon-question-sign get-help hover-help"
+ <span class="text-muted">satisfied via <code class="text-muted">{{rr.via.name}}</code></span>
+ <span class="glyphicon glyphicon-question-sign get-help hover-help"
title="This dependency is satisfied by the PROVIDES value
- {{rr.via.name}} in the {{rr.depends_on.name}} recipe"></i>
+ <code>{{rr.via.name}}</code> in the <code>{{rr.depends_on.name}}</code> recipe"></span>
{% endif %}
</td>
- <td><a href="{% url "recipe" build.pk rr.depends_on.pk %}">{{rr.depends_on.version}}</a></td>
+ <td>{{rr.depends_on.version}}</td>
</tr>
{% endfor %}
@@ -213,13 +262,13 @@
<tr>
<td><a href="{% url "recipe" build.pk rr.recipe.pk %}">{{rr.recipe.name}}</a>
{% if rr.via %}
- <span class="muted"> satisfied via {{rr.via.name}}</span>
- <i class="icon-question-sign get-help hover-help"
+ <span class="text-muted"> satisfied via <code class="text-muted">{{rr.via.name}}</code></span>
+ <span class="glyphicon glyphicon-question-sign get-help hover-help"
title="This dependency is satisfied by the PROVIDES value
- {{rr.via.name}} in the {{rr.depends_on.name}} recipe"></i>
+ <code>{{rr.via.name}}</code> in the <code>{{rr.depends_on.name}}</code> recipe"></i>
{% endif %}
</td>
- <td><a href="{% url "recipe" build.pk rr.recipe.pk %}">{{rr.recipe.version}}</a></td>
+ <td>{{rr.recipe.version}}</td>
</tr>
{% endfor %}
@@ -231,7 +280,8 @@
</div>
</div>
-<div class="row span4 well">
+<div class="col-md-4">
+ <div class="well">
<h2>About {{object.name}}</h2>
<dl class="item-info">
{% if object.summary %}
@@ -253,7 +303,7 @@
{% if object.section %}
<dt>
Section
- <i class="icon-question-sign get-help" title="The section in which recipes should be categorized"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The section in which recipes should be categorized"></span>
</dt>
<dd>{{object.section}}</dd>
{% endif %}
@@ -262,6 +312,9 @@
<dd>{{object.license}}</dd>
{% endif %}
</dl>
+ </div>
</div>
+</div> <!-- end row -->
+
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_btn.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_btn.html
index baab06eb5..e3729643a 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_btn.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_btn.html
@@ -1,16 +1,17 @@
-<button data-recipe-name="{{data.name}}" class="btn btn-block layer-exists-{{data.layer_version.pk}} build-recipe-btn" style="margin-top: 5px;
+<a data-recipe-name="{{data.name}}" class="btn btn-default btn-block layer-exists-{{data.layer_version.pk}} build-recipe-btn" style="margin-top: 5px;
{% if data.layer_version.pk not in extra.current_layers %}
display:none;
{% endif %}"
>
Build recipe
-</button>
-<button class="btn btn-block layerbtn layer-add-{{data.layer_version.pk}}" data-layer='{ "id": {{data.layer_version.pk}}, "name": "{{data.layer_version.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.pk%}"}' data-directive="add"
+</a>
+<a class="btn btn-default btn-block layerbtn layer-add-{{data.layer_version.pk}}" data-layer='{ "id": {{data.layer_version.pk}}, "name": "{{data.layer_version.layer.name}}", "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.pk%}"}' data-directive="add"
{% if data.layer_version.pk in extra.current_layers %}
style="display:none;"
{% endif %}
>
- <i class="icon-plus"></i>
+ <span class="glyphicon glyphicon-plus"></span>
Add layer
- <i title="" class="icon-question-sign get-help" data-original-title="To build this target, you must first add the {{data.layer_version.layer.name}} layer to your project"></i>
-</button>
+ <span class="glyphicon glyphicon-question-sign get-help" title="To build this
+ recipe you must first add the {{data.layer_version.layer.name}} layer to your project"></i>
+</a>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_packages.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_packages.html
index d25847bc0..37a586f38 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_packages.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipe_packages.html
@@ -11,35 +11,43 @@
<!-- Begin container -->
-<div class="row-fluid span11">
- <div class="page-header">
+<div class="row">
+ <div class="col-md-12">
+ <div class="page-header build-data">
<h1>{{recipe.name}}_{{recipe.version}}</h1>
</div>
+ </div>
</div>
-<div class="row-fluid span7 tabbable">
- <ul class="nav nav-pills">
+<div class="row">
+ <div class="col-md-8 tabbable">
+ <ul class="nav nav-tabs">
<li>
<a href="{% url "recipe" build.pk recipe.id "1" %}">
- <i class="icon-question-sign get-help" title="Build-related information about the recipe"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Build-related
+ information about the recipe"></span>
Recipe details
</a>
</li>
<li class="active">
- <a href="#packages-built" data-toggle="tab">
- <i class="icon-question-sign get-help" title="The packaged output resulting from building the recipe"></i>
+ <a href="#packages-built" data-toggle="tab">
+ <span class="glyphicon glyphicon-question-sign get-help" title="The packaged
+ output resulting from building the recipe"></span>
Packages ({{object_count}})
</a>
</li>
<li>
<a href="{% url "recipe" build.pk recipe.id "3" %}">
- <i class="icon-question-sign get-help" title="The recipe build-time dependencies (i.e. other recipes)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The recipe
+ build-time dependencies (i.e. other recipes)"></span>
Build dependencies ({{recipe.r_dependencies_recipe.all.count}})
</a>
</li>
<li>
<a href="{% url "recipe" build.pk recipe.id "4" %}">
- <i class="icon-question-sign get-help" title="The recipe build-time reverse dependencies (i.e. the recipes that depend on this recipe)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The recipe
+ build-time reverse dependencies (i.e. the recipes that
+ depend on this recipe)"></span>
Reverse build dependencies ({{recipe.r_dependencies_depends.all.count}})
</a>
</li>
@@ -72,8 +80,8 @@
<tr>
<td><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.name}}</a></td>
- <td><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.version}}_{{package.revision}}</a></td>
- <td class="sizecol"><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.size|filtered_filesizeformat}}</a></td>
+ <td>{{package.version}}_{{package.revision}}</td>
+ <td class="sizecol">{{package.size|filtered_filesizeformat}}</td>
</tr>
{% endfor %}
@@ -86,9 +94,10 @@
{% endif %}
</div> {# tab-pane #}
</div> {# tab-content #}
-</div> {# span7 #}
+</div> {# col-md-8 #}
-<div class="row span4 well">
+<div class="col-md-4">
+ <div class="well">
<h2>About {{recipe.name}}</h2>
<dl class="item-info">
{% if recipe.summary %}
@@ -119,5 +128,8 @@
<dd>{{recipe.license}}</dd>
{% endif %}
</dl>
+ </div>
</div>
+
+</div> <!-- end row -->
{% endblock pagedetailinfomain %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipedetails.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipedetails.html
index 23aa171ce..66c1f7bcd 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipedetails.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipedetails.html
@@ -4,25 +4,23 @@
{% load static %}
{% block pagecontent %}
-<div class="section">
- <ul class="breadcrumb">
- <li>
- <a href="{% url 'project' project.id %}">{{project.name}}</a>
- <span class="divider">&rarr;</span>
- </li>
- <li>
- {% if recipe.is_image %}
- <a href="{% url 'projectimagerecipes' project.id %}">Image recipes</a>
- {% else %}
- <a href="{% url 'projectsoftwarerecipes' project.id %}">Software recipes</a>
- {% endif %}
- <span class="divider">&rarr;</span>
- </li>
- <li class="active">
- {{recipe.name}} ({{recipe.layer_version.layer.name}})
- </li>
- </ul>
-</div>
+<ul class="breadcrumb">
+ <li>
+ <a href="{% url 'project' project.id %}">{{project.name}}</a>
+ <span class="divider">&rarr;</span>
+ </li>
+ <li>
+ {% if recipe.is_image %}
+ <a href="{% url 'projectimagerecipes' project.id %}">Image recipes</a>
+ {% else %}
+ <a href="{% url 'projectsoftwarerecipes' project.id %}">Software recipes</a>
+ {% endif %}
+ <span class="divider">&rarr;</span>
+ </li>
+ <li class="active">
+ {{recipe.name}} ({{recipe.layer_version.layer.name}})
+ </li>
+</ul>
<script src="{% static 'js/recipedetails.js' %}"></script>
<script>
@@ -51,42 +49,40 @@
{% include 'newcustomimage_modal.html' %}
-<div class="row-fluid span11">
- <div class="alert alert-success lead" id="image-created-notification" style="margin-top: 15px; display: none">
- <button type="button" data-dismiss="alert" class="close">x</button>
- Your custom image <strong>{{recipe.name}}</strong> has been created. You can now add or remove packages as needed.
- </div>
- <div class="page-header air">
- <h1>
- {{recipe.name}}
- <small>({{recipe.layer_version.layer.name}})</small>
- </h1>
- </div>
+<div class="alert alert-success lead" id="image-created-notification" style="margin-top: 15px; display: none">
+ <button type="button" data-dismiss="alert" class="close">x</button>
+ Your custom image <strong>{{recipe.name}}</strong> has been created. You can now add or remove packages as needed.
+</div>
+<div class="page-header">
+ <h1>
+ {{recipe.name}}
+ <small>({{recipe.layer_version.layer.name}})</small>
+ </h1>
</div>
-<div class="row-fluid span11">
- <div class="span8">
+<div class="row">
+ <div class="col-md-8">
<div class="button-place btn-group" id="customise-build-btns"
style="width: 100%;
{% if not in_project %}
display:none;
{% endif %}">
- <button class="btn btn-large span6 build-recipe-btn" style="width: 50%">
+ <button class="btn btn-default btn-lg build-recipe-btn" style="width: 50%">
Build {{recipe.name}}
</button>
{% if recipe.is_image %}
- <button class="btn btn-large span6 customise-btn" data-recipe="{{recipe.pk}}" style="width: 50%">
+ <button class="btn btn-default btn-lg customise-btn" data-recipe="{{recipe.pk}}" style="width: 50%">
Customise {{recipe.name}}
</button>
{% endif %}
</div>
<div class="button-place">
- <button class="btn btn-block btn-large" id="add-layer-btn"
+ <button class="btn btn-default btn-block btn-lg" id="add-layer-btn"
style="width:100%;
{% if in_project %}
display:none;
{% endif %}">
- <i class="icon-plus"></i>
+ <i class="glyphicon glyphicon-plus"></i>
Add the {{recipe.layer_version.layer.name}} layer to your project to build or customise this image recipe
</button>
</div>
@@ -106,7 +102,7 @@
style="display:none"
{% endif %} >
<p class="lead">Toaster has no package information for {{recipe.name}}. To generate package information, build {{recipe.name}}</p>
- <button class="btn btn-info btn-large build-recipe-btn" style="margin:20px 0 10px 0;">Build {{recipe.name}}</button>
+ <button class="btn btn-info btn-lg build-recipe-btn" style="margin:20px 0 10px 0;">Build {{recipe.name}}</button>
</div>
<div class="alert alert-info air" id="packages-alert"
@@ -119,58 +115,60 @@
</div>
</div>
</div>
- <div class="span4 well">
- <h2 style="margin-bottom:20px;">About {{recipe.name}}</h2>
- <dl>
- <dt>
+ <div class="col-md-4">
+ <div class="well">
+ <h2>About {{recipe.name}}</h2>
+ <dl class="item-info">
+ <dt>
Approx. packages included
- <i class="icon-question-sign get-help" title="" data-original-title="The number of packages included is based on information from previous builds and from parsing layers, so we can never be sure it is 100% accurate"></i>
- </dt>
- <dd class="no-packages">{{packages.count}}</dd>
- <dt>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The number of packages included is based on information from previous builds and from parsing layers, so we can never be sure it is 100% accurate"></span>
+ </dt>
+ <dd class="no-packages">{{packages.count}}</dd>
+ <dt>
Approx. package size
- <i class="icon-question-sign get-help" title="" data-original-title="Package size is based on information from previous builds, so we can never be sure it is 100% accurate"></i>
- </dt>
- <dd>{{approx_pkg_size.size__sum|filtered_filesizeformat}}</dd>
- {% if last_build %}
- <dt>Last build</dt>
- <dd>
- <i class="icon-ok-sign success"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Package size is based on information from previous builds, so we can never be sure it is 100% accurate"></span>
+ </dt>
+ <dd>{{approx_pkg_size.size__sum|filtered_filesizeformat}}</dd>
+ {% if last_build %}
+ <dt>Last build</dt>
+ <dd>
+ <span class="glyphicon glyphicon-ok-circle"></span>
<a href="{% url 'projectbuilds' project.id%}">{{last_build.completed_on|date:"d/m/y H:i"}}</a>
- </dd>
- {% endif %}
- <dt>Recipe file</dt>
- <dd>
+ </dd>
+ {% endif %}
+ <dt>Recipe file</dt>
+ <dd>
<code>{{recipe.file_path|cut_path_prefix:recipe.layer_version.local_path}}</code>
- <a href="{{recipe.get_vcs_recipe_file_link_url}}"><i class="icon-share" title="" data-original-title="View recipe file"></i></a>
- </dd>
- <dt>Layer</dt>
- <dd><a href="{% url 'layerdetails' project.id recipe.layer_version.pk %}">{{recipe.layer_version.layer.name}}</a></dd>
- <dt>
+ <a href="{{recipe.get_vcs_recipe_file_link_url}}"><span class="glyphicon glyphicon-new-window" title="View recipe file" data-toggle="tooltip"></span></a>
+ </dd>
+ <dt>Layer</dt>
+ <dd><a href="{% url 'layerdetails' project.id recipe.layer_version.pk %}">{{recipe.layer_version.layer.name}}</a></dd>
+ <dt>
Summary
- </dt>
- <dd>
+ </dt>
+ <dd>
{{recipe.summary}}
- </dd>
- <dt>
+ </dd>
+ <dt>
Description
- </dt>
- <dd>
+ </dt>
+ <dd>
{{recipe.description}}
- </dd>
- <dt>Version</dt>
- <dd>
+ </dd>
+ <dt>Version</dt>
+ <dd>
{{recipe.version}}
- </dd>
- <dt>Section</dt>
- <dd>
+ </dd>
+ <dt>Section</dt>
+ <dd>
{{recipe.section}}
- </dd>
- <dt>License</dt>
- <dd>
+ </dd>
+ <dt>License</dt>
+ <dd>
{{recipe.license}}
- </dd>
- </dl>
+ </dd>
+ </dl>
+ </div>
</div>
</div>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipes.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipes.html
deleted file mode 100644
index d14489346..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/recipes.html
+++ /dev/null
@@ -1,113 +0,0 @@
-{% extends "basebuildpage.html" %}
-
-{% load projecttags %}
-
-{% block title %} Recipes - {{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}} - {{build.project.name}} - Toaster {% endblock %}
-{% block localbreadcrumb %}
-<li>Recipes</li>
-{% endblock %}
-
-{% block nav-recipes %}
- <li class="active"><a href="{% url 'recipes' build.pk %}">Recipes</a></li>
-{% endblock %}
-
-{% block buildinfomain %}
-<div class="span10">
-<div class="page-header">
-<h1>
- {% if request.GET.search and objects.paginator.count > 0 %}
- {{objects.paginator.count}} recipe{{objects.paginator.count|pluralize}} found
- {%elif request.GET.search and objects.paginator.count == 0%}
- No recipes found
- {%else%}
- Recipes
- {%endif%}
- </h1>
-</div>
-
-{% if objects.paginator.count == 0 %}
- <div class="row-fluid">
- <div class="alert">
- <form class="no-results input-append" id="searchform">
- <input id="search" name="search" class="input-xxlarge" type="text" value="{%if request.GET.search%}{{request.GET.search}}{%endif%}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
- <button class="btn" type="submit" value="Search">Search</button>
- <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all recipes</button>
- </form>
- </div>
- </div>
-
-{% else %}
-{% include "basetable_top.html" %}
-
- {% for recipe in objects %}
-
- <tr class="data">
- <td class="recipe__name">
- <a href="{% url "recipe" build.pk recipe.pk %}">{{recipe.name}}</a>
- </td>
- <td class="recipe__version">
- <a href="{% url "recipe" build.pk recipe.pk %}">{{recipe.version}}</a>
- </td>
- <!-- Depends -->
- <td class="depends_on">
- {% with deps=recipe_deps|get_dict_value:recipe.pk %}
- {% with count=deps|length %}
- {% if count %}
- <a class="btn"
- title="<a href='{% url "recipe" build.pk recipe.pk %}#dependencies'>{{recipe.name}}</a> dependencies"
- data-content="<ul class='unstyled'>
- {% for i in deps|dictsort:"depends_on.name"%}
- <li><a href='{% url "recipe" build.pk i.depends_on.pk %}'>{{i.depends_on.name}}</a></li>
- {% endfor %}
- </ul>">
- {{count}}
- </a>
- {% endif %}
- {% endwith %}
- {% endwith %}
- </td>
- <!-- Brought in by -->
- <td class="depends_by">
- {% with revs=recipe_revs|get_dict_value:recipe.pk %}
- {% with count=revs|length %}
- {% if count %}
- <a class="btn"
- title="<a href='{% url "recipe" build.pk recipe.pk %}#brought-in-by'>{{recipe.name}}</a> reverse dependencies"
- data-content="<ul class='unstyled'>
- {% for i in revs|dictsort:"recipe.name" %}
- <li><a href='{% url "recipe" build.pk i.recipe.pk %}'>{{i.recipe.name}}</a></li>
- {% endfor %}
- </ul>">
- {{count}}
- </a>
- {% endif %}
- {% endwith %}
- {% endwith %}
- </td>
- <!-- Recipe file -->
- <td class="recipe_file">{{recipe.file_path}} {% if recipe.pathflags %}<i>({{recipe.pathflags}})</i>{% endif %}</td>
- <!-- Section -->
- <td class="recipe_section">{{recipe.section}}</td>
- <!-- License -->
- <td class="recipe_license">{{recipe.license}}</td>
- <!-- Layer -->
- <td class="layer_version__layer__name">{{recipe.layer_version.layer.name}}</td>
- <!-- Layer branch -->
- <td class="layer_version__branch">{{recipe.layer_version.branch}}</td>
- <!-- Layer commit -->
- <td class="layer_version__layer__commit">
- <a class="btn"
- data-content="<ul class='unstyled'>
- <li>{{recipe.layer_version.commit}}</li>
- </ul>">
- {{recipe.layer_version.commit|truncatechars:13}}
- </a>
- </td>
- </tr>
-
- {% endfor %}
-
-{% include "basetable_bottom.html" %}
-{% endif %}
-</div>
-{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html
new file mode 100644
index 000000000..c1e3dabfb
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html
@@ -0,0 +1,8 @@
+{% load projecttags %}
+{% if vcs_ref|is_shaid %}
+<a class="btn btn-default" data-content="{{vcs_ref}}">
+ {{vcs_ref|truncatechars:10}}
+</a>
+{% else %}
+{{vcs_ref}}
+{% endif %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html
index a3fcdb09e..273437e38 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html
@@ -1,14 +1,38 @@
{# Popover that displays the dependences and sizes of a package 'data' used in the Packages table #}
-{% with data.package_dependencies_source.all_depends.count as dep_count %}
{% load projecttags %}
-{% if dep_count %}
- <a data-content="<ul class='unstyled'>
- {% for dep in data.package_dependencies_source.all_depends %}
- <li>{{dep.depends_on.name}} {% if dep.depends_on.size > 0 %}({{dep.depends_on.size|filtered_filesizeformat}}){% endif %}</li>
- {% endfor %}
- </ul>" title="" class="btn" data-original-title="
- <strong>{{data.name}}</strong> dependencies - <strong>{{data.package_dependencies_source.get_total_source_deps_size.depends_on__size__sum|filtered_filesizeformat}}</strong>">
- {{dep_count}}
-</a>
+
+{% with package_deps=data.package_dependencies_source|for_target:extra.target_name %}
+{% with count_package=package_deps.packages|length %}
+
+{% if count_package > 0 %}
+ <a data-content='<ul class="list-unstyled">
+ {% for dep in package_deps.packages %}
+ <li>
+ {% if extra.add_links %}
+ <a href="{% url 'package_included_detail' extra.build.pk extra.target_id dep.depends_on.pk %}">
+ {{dep.depends_on.name}}</a>
+ {% else %}
+ {{dep.depends_on.name}}
+ {% endif %}
+ {% if dep.depends_on.size > 0 %}
+ ({{dep.depends_on.size|filtered_filesizeformat}})
+ {% endif %}
+ </li>
+ {% endfor %}
+ </ul>' class="btn btn-default" title='
+ <strong>
+ {% if extra.add_links %}
+ <a href="{% url 'package_included_dependencies' extra.build.pk extra.target_id data.pk %}">
+ {{data.name}}</a>
+ {% else %}
+ {{data.name}}
+ {% endif %}
+ </strong>
+ dependencies -
+ <strong>{{package_deps.size|filtered_filesizeformat}}</strong>'>
+ {{count_package}}
+ </a>
{% endif %}
+
+{% endwith %}
{% endwith %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html
index 453a9d013..e6ef816e7 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html
@@ -1,14 +1,38 @@
-{# Popover that displays the reverse dependencies and sizes of a package 'data' used in the Packages table #}
-{% with data.package_dependencies_target.all_depends.count as dep_count %}
+{# Popover that displays the reverse dependences and sizes of a package 'data' used in the Packages table #}
{% load projecttags %}
-{% if dep_count %}
- <a data-content="<ul class='unstyled'>
- {% for dep in data.package_dependencies_target.all_depends|dictsort:'package.name' %}
- <li>{{dep.package.name}} {% if dep.package.size > 0 %}({{dep.package.size|filtered_filesizeformat}}){% endif %}</li>
- {% endfor %}
- </ul>" title="" class="btn" data-original-title="
- <strong>{{data.name}}</strong> reverse dependencies - <strong>{{data.package_dependencies_target.get_total_revdeps_size.package_id__size__sum|filtered_filesizeformat}}</strong>">
- {{dep_count}}
-</a>
+
+{% with package_deps=data.package_dependencies_target|for_target:extra.target_name %}
+{% with count_package=package_deps.packages|length %}
+
+{% if count_package > 0 %}
+ <a data-content='<ul class="list-unstyled">
+ {% for dep in package_deps.packages|dictsort:"package.name" %}
+ <li>
+ {% if extra.add_links %}
+ <a href="{% url 'package_included_detail' extra.build.pk extra.target_id dep.package.pk %}">
+ {{dep.package.name}}</a>
+ {% else %}
+ {{dep.package.name}}
+ {% endif %}
+ {% if dep.package.size > 0 %}
+ ({{dep.package.size|filtered_filesizeformat}})
+ {% endif %}
+ </li>
+ {% endfor %}
+ </ul>' class="btn btn-default" title='
+ <strong>
+ {% if extra.add_links %}
+ <a href="{% url 'package_included_reverse_dependencies' extra.build.pk extra.target_id data.pk %}">
+ {{data.name}}</a>
+ {% else %}
+ {{data.name}}
+ {% endif %}
+ </strong>
+ dependencies -
+ <strong>{{package_deps.size|filtered_filesizeformat}}</strong>'>
+ {{count_package}}
+ </a>
{% endif %}
+
+{% endwith %}
{% endwith %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/target.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/target.html
index 4c33eaa84..1924a0dad 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/target.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/target.html
@@ -17,9 +17,8 @@
{% endblock %}
{% block buildinfomain %}
-
-<div class="row-fluid span10">
- <div class="page-header">
+<div class="col-md-10">
+ <div class="page-header build-data">
<h1>
{% if request.GET.search and objects.paginator.count > 0 %}
{{objects.paginator.count}} package{{objects.paginator.count|pluralize}} found
@@ -30,134 +29,28 @@
{% endif %}
</h1>
</div>
-</div>
-
-<div class="row-fluid pull-right span10" id="navTab">
- <ul class="nav nav-pills">
+<div id="navTab">
+ <ul class="nav nav-tabs">
<li class="active">
<a href="#target">
- <i class="icon-question-sign get-help" title="Of all the packages built, the subset installed in the root file system of this image"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Of all the packages built, the subset installed in the root file system of this image"></span>
Packages included ({{target.package_count}} - {{packages_sum|filtered_filesizeformat}})
</a>
</li>
<li>
<a href="{% url 'dirinfo' build.id target.id %}">
- <i class="icon-question-sign get-help" title="The directories and files in the root file system of this image"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The directories and files in the root file system of this image"></span>
Directory structure
</a>
</li>
</ul>
<div id="image-packages" class="tab-pane">
-
- {% if objects.paginator.count == 0 %}
- <div class="row-fluid">
- <div class="alert">
- <form class="no-results input-append" id="searchform">
- <input id="search" name="search" class="input-xxlarge" type="text" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
- <button class="btn" type="submit" value="Search">Search</button>
- <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all packages</button>
- </form>
- </div>
- </div>
-
-
- {% else %}
- {% include "basetable_top.html" %}
- {% for package in objects %}
- <tr>
- {# order of the table data must match the columns defined in template's context tablecols #}
- <td class="package_name">
- <a href="{% url 'package_included_detail' build.id target.id package.id %}">
- {{package.name}}
- </a>
- {% if package.installed_name and package.name != package.installed_name %}
- <span class="muted"> as {{package.installed_name}}</span>
- <i class="icon-question-sign get-help hover-help" title='{{package.name|add:" was renamed at packaging time and was installed in your image as "|add:package.installed_name}}'></i>
- {% endif %}
- </td>
- <td class="package_version">
- <a href="{% url 'package_included_detail' build.id target.id package.id %}">
- {{package.version|filtered_packageversion:package.revision}}
- </a>
- </td>
- <td class="license">
- {{package.license}}
- </td>
- <td class="size sizecol">
- {{package.size|filtered_installedsize:package.installed_size|filtered_filesizeformat}}
- </td>
-
- <td class="size_over_total sizecol">
- {{package|filter_sizeovertotal:packages_sum}}
- </td>
- <td class="depends">
- {% with deps=package.runtime_dependencies %}
- {% with deps_count=deps|length %}
- {% if deps_count > 0 %}
- <a class="btn"
- title="<a href='{% url "package_included_dependencies" build.id target.id package.id %}'>{{package.name}}</a> dependencies"
- data-content="<ul class='unstyled'>
- {% for i in deps|dictsort:'depends_on.name' %}
- <li><a href='{% url "package_included_detail" build.pk target.id i.depends_on.pk %}'>{{i.depends_on.name}}</a></li>
- {% endfor %}
- </ul>">
- {{deps_count}}
- </a>
- {% endif %}
- {% endwith %}
- {% endwith %}
- </td>
- <td class="brought_in_by">
- {% with rdeps=package.reverse_runtime_dependencies %}
- {% with rdeps_count=rdeps|length %}
- {% if rdeps_count > 0 %}
- <a class="btn"
- title="<a href='{% url "package_included_reverse_dependencies" build.id target.id package.id %}'>{{package.name}}</a> reverse dependencies"
- data-content="<ul class='unstyled'>
- {% for i in rdeps|dictsort:'package.name' %}
- <li><a href='{% url "package_included_detail" build.id target.id i.package.id %}'>{{i.package.name}}</a></li>
- {% endfor %}
- </ul>">
- {{rdeps_count}}
- </a>
- {% endif %}
- {% endwith %}
- {% endwith %}
- </td>
- <td class="recipe_name">
- {% if package.recipe.version %}
- <a href="{% url 'recipe' build.id package.recipe_id %}">
- {{ package.recipe.name }}
- </a>
- {% endif %}
- </td>
- <td class="recipe_version">
- {% if package.recipe.version %}
- <a href="{% url 'recipe' build.id package.recipe_id %}">
- {{ package.recipe.version }}
- </a>
- {% endif %}
- </td>
- <td class="layer_name">
- {{ package.recipe.layer_version.layer.name }}
- </td>
- <td class="layer_branch">
- {{ package.recipe.layer_version.branch}}
- </td>
- <td class="layer_commit">
- <a class="btn"
- data-content="<ul class='unstyled'>
- <li>{{package.recipe.layer_version.commit}}</li>
- </ul>">
- {{package.recipe.layer_version.commit|truncatechars:13}}
- </a>
- </td>
- </tr>
- {% endfor %}
-
- {% include "basetable_bottom.html" %}
- {% endif %}
+ {# xhr_table_url is just the current url so leave it blank #}
+ {% with xhr_table_url='' %}
+ {% include "toastertable.html" %}
+ {% endwith %}
</div> <!-- tabpane -->
-</div> <!--span 10-->
+ </div> <!--navTab -->
+<!-- col-md-10 -->
{% endblock buildinfomain %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/task.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/task.html
index 576826243..214c77783 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/task.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/task.html
@@ -11,60 +11,88 @@
{% block pagedetailinfomain %}
-<div class="row span11">
- <div class="page-header">
+<div class="row">
+ <div class="col-md-12">
+ <div class="page-header build-data">
<h1><a href="{%url 'recipe' build.pk task.recipe.pk %}">{{task.recipe.name}}_{{task.recipe.version}}</a> {{task.task_name}}</h1>
</div>
{# Outcome section #}
<h2 {{ task|task_color:True }}>
{{task.get_outcome_display}}
- <i class="icon-question-sign get-help heading-help" title="{{task.get_outcome_help}}"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="{{task.get_outcome_help}}"></i>
</h2>
{%if task.task_executed %}
{# executed tasks outcome #}
{% if task.logfile %}
- <a class="btn btn-large" href="{% url 'build_artifact' build.id "tasklogfile" task.pk %}" style="margin:15px;">Download task log</a>
+ <a class="btn btn-default btn-lg"
+ href="{% url 'build_artifact' build.id 'tasklogfile' task.pk %}">
+ Download task log
+ </a>
{% endif %}
{# show stack trace for failed task #}
{% if task.outcome == task.OUTCOME_FAILED and log_head %}
<h3>Python stack trace</h3>
<div>
<pre style="min-height:160px;">
- <code>{{log_head}}</code><a id="full-trace-show" data-target="#fulltrace" data-toggle="collapse" class="btn btn-mini">...</a>
+ <code>{{log_head}}</code><a id="full-trace-show" data-target="#fulltrace" data-toggle="collapse" class="btn btn-xs">...</a>
<div id="fulltrace" class="collapse" style="margin-top: -20px; height: 0px;">
- <code>{{log_body}}</code><br><a id="full-trace-hide" class="btn btn-mini collapsed" style="font-family:Helvetica Neue" data-target="#fulltrace" data-toggle="collapse">Collapse stack trace<i class="icon-caret-up"></i></a></div></pre>
+ <code>{{log_body}}</code><br><a id="full-trace-hide" class="btn btn-xs collapsed" style="font-family:Helvetica Neue" data-target="#fulltrace" data-toggle="collapse">Collapse stack trace<i class="icon-caret-up"></i></a></div></pre>
</div>
{% endif %}
{% else %}
{# not executed tasks outcome #}
{% if task.outcome == task.OUTCOME_PREBUILT %}
{% if not showing_matches %}
- <a class="btn" href="javascript:reload_params({'show_matches' : 'true' })">Match to tasks in previous builds <i class="icon-question-sign get-help" style="margin-top:20px;" title="This shows you a list of tasks from previous builds with the same signature generated from the same inputs as used in the prebuilt task. Any of them could be the task that generated the output this prebuilt task is reusing"></i></a>
+ <a class="btn btn-default"
+ href="javascript:reload_params({'show_matches' : 'true'
+ })">Match to tasks in previous builds <span class="glyphicon
+glyphicon-question-sign get-help" title="This shows you a list of tasks from
+previous builds with the same signature generated from the same inputs as used
+in the prebuilt task. Any of them could be the task that generated the output
+this prebuilt task is reusing"></span></a>
{% elif matching_tasks %}
<h3 class="details">Prebuilt task could be based on
- <i class="icon-question-sign get-help heading-help" title="This table shows a list of tasks from previous builds with the same signature generated from the same inputs as used in the prebuilt task. Any of them could be the task that generated the output this prebuilt task is reusing"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="This
+ table shows a list of tasks from previous builds with the
+ same signature generated from the same inputs as used in the
+ prebuilt task. Any of them could be the task that generated the
+ output this prebuilt task is reusing"></span>
</h3>
+ <div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<th>
- <i class="icon-question-sign get-help" title="The name of the recipe to which each task applies"></i>
+ <span class="glyphicon glyphicon-question-sign
+ get-help" title="The name of the recipe to which
+ each task applies"></span>
Recipe
</th>
<th>
- <i class="icon-question-sign get-help" title="The name of the task"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The name
+ of the task"></span>
Task
</th>
<th>
- <i class="icon-question-sign get-help" title="This value tells you if a task had to run (executed) in order to generate the task output, or if the output was provided by another task and therefore the task didn't need to run (not executed)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="This
+ value tells you if a task had to run (executed) in
+ order to generate the task output, or if the output was
+ provided by another task and therefore the task didn't need
+ to run (not executed)"></span>
Executed
</th>
<th>
- <i class="icon-question-sign get-help" title="This column tells you if 'executed' tasks succeeded or failed. The column also tells you why 'not executed' tasks did not need to run"></i>
+ <span class="glyphicon glyphicon-question-sign
+ get-help" title="This column tells you if
+ 'executed' tasks succeeded or failed. The column also
+ tells you why 'not executed' tasks did not need to
+ run"></span>
Outcome
</th>
<th>
- <i class="icon-question-sign get-help" title="The date and time the build finished"></i>
+ <span class="glyphicon glyphicon-question-sign
+ get-help" title="The date and time the build
+ finished"></span>
Build completed on
</th>
</thead>
@@ -72,27 +100,34 @@
{% for match in matching_tasks %}
<tr {{ match|task_color }}>
<td>
- <a href="{%url "task" match.build.pk match.pk%}">{{match.recipe.name}}</a>
+ {{match.recipe.name}}
</td>
<td>
<a href="{%url "task" match.build.pk match.pk%}">{{match.task_name}}</a>
{% if task.get_description %}
- <i class="icon-question-sign get-help hover-help" title="{{task.get_description}}"></i>
+ <span class="glyphicon
+ glyphicon-question-sign get-help
+ hover-help"
+ title="{{task.get_description}}"></span>
{% endif %}
</td>
<td>
- <a href="{%url "task" match.build.pk match.pk%}">{{match.get_executed_display}}</a>
+ {{match.get_executed_display}}
</td>
<td>
- <a href="{%url "task" match.build.pk match.pk%}">{{match.get_outcome_display}} </a><i class="icon-question-sign get-help hover-help" title="{{match.get_outcome_help}}"></i>
+ {{match.get_outcome_display}}
+ <span class="glyphicon glyphicon-question-sign
+ get-help hover-help"
+ title="{{match.get_outcome_help}}"></span>
</td>
<td>
- <a href="{%url "task" match.build.pk match.pk%}">{{match.build.completed_on|date:"d/m/y H:i"}}</a>
+ {{match.build.completed_on|date:"d/m/y H:i"}}
</td>
</tr>
{% endfor %}
</tbody>
</table>
+ </div>
{% else %}
<p class="alert">
<strong> We have found no tasks matching this prebuilt task</strong><br/>
@@ -102,10 +137,11 @@
{% elif task.outcome == task.OUTCOME_COVERED %}
<dl class="dl-horizontal">
<dt>
- <i class="icon-question-sign get-help" title="The task(s) providing the outcome of this task"></i> Task covered by
+ <span class="glyphicon glyphicon-question-sign get-help" title="The task(s)
+ providing the outcome of this task"></span> Task covered by
</dt>
<dd>
- <ul>
+ <ul class="list-unstyled">
{% for t in covered_by %}
<li>
<a href="{%url 'task' t.build.pk t.pk%}"
@@ -122,7 +158,10 @@
{%elif task.outcome == task.OUTCOME_CACHED%}
{% for t in task.get_related_setscene %}
{% if forloop.last %}
- <a class="btn btn-large" href="{% url 'build_artifact' build.id "tasklogfile" t.pk %}" style="margin:15px;">Download task log</a>
+ <a class="btn btn-default btn-lg"
+ href="{% url 'build_artifact' build.id "tasklogfile" t.pk %}">
+ Download task log
+ </a>
{% endif %}
{% endfor %}
@@ -137,38 +176,56 @@
{% if task.task_executed %}
<h2>
Executed
- <i class="icon-question-sign get-help heading-help" title="'Executed' tasks are those that need to run in order to generate the task output"></i>
+ <span class="glyphicon glyphicon-question-sign get-help"
+ title="'Executed' tasks are those that need to run in order to
+ generate the task output"></span>
{% else %}
- <h2 class="muted">
+ <h2>
Not Executed
- <i class="icon-question-sign get-help heading-help" title="'Not executed' tasks don't need to run because their outcome is provided by another task"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="'Not
+ executed' tasks don't need to run because their outcome is provided
+ by another task"></span>
{% endif %}
</h2>
<dl class="dl-horizontal">
<dt>
- <i class="icon-question-sign get-help" title="To make builds more efficient, the build system detects changes in the 'inputs' to a given task by creating a 'task signature'. If the signature changes, the build system assumes the inputs have changed and the task needs to be rerun"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="To make builds more
+ efficient, the build system detects changes in the 'inputs' to a
+ given task by creating a 'task signature'. If the signature changes,
+ the build system assumes the inputs have changed and the task needs to be
+rerun"></span>
Task inputs signature
</dt>
<dd>
{{task.sstate_checksum}}
</dd>
-</dl>
{% if task.sstate_result != task.SSTATE_NA %}
+ </dl>
<div class="alert alert-info">Attempting to restore output from sstate cache
- <i class="icon-question-sign get-help get-help-blue" title="The build system is searching for the task output in your <code>sstate-cache</code> directory and mirrors. If the build system finds the task output, it will reuse it instead of building it from scratch by running the real task. Reusing the task output makes the build faster"></i>
+ <span class="glyphicon glyphicon-question-sign get-help
+ get-help-blue" title="The build system is searching for the
+ task output in your <code>sstate-cache</code> directory and
+ mirrors. If the build system finds the task output, it will reuse it
+ instead of building it from scratch by running the real task. Reusing the
+ task output makes the build faster"></span>
</div>
<dl class="dl-horizontal">
<dt>
- <i class="icon-question-sign get-help" title="The name of the file searched for in your <code>sstate-cache</code> directory and mirrors"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The name of the
+ file searched for in your <code>sstate-cache</code>
+ directory and mirrors"></span>
File searched for
</dt>
<dd><code>{{task.path_to_sstate_obj}}</code></dd>
<dt>
- <i class="icon-question-sign get-help" title="The locations searched for the above file (i.e. your <code>sstate-cache</code> directory and any mirrors you have set up)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The locations
+ searched for the above file (i.e. your
+ <code>sstate-cache</code> directory and any mirrors you have
+ set up)"></span>
URI(s) searched
</dt>
- <dd><ul>{% for uri in uri_list %}<li><code>{{uri}}</code></li>{% endfor %}</ul></dd>
+ <dd><ul class="list-unstyled">{% for uri in uri_list %}<li><code>{{uri}}</code></li>{% endfor %}</ul></dd>
</dl>
{% endif %}
{% if task.sstate_result == task.SSTATE_MISS %}
@@ -176,7 +233,7 @@
<strong>File not in sstate cache.</strong> Running the real task instead.
</div>
{% elif task.sstate_result == task.SSTATE_FAILED%}
- <div class="alert">
+ <div class="alert alert-warning">
<strong>Failed</strong> to restore output from sstate cache. The file was found but could not be unpacked.
</div>
<dl class="dl-horizontal">
@@ -192,13 +249,16 @@
{% endif %}
<dl class="dl-horizontal">
<dt>
- <i class="icon-question-sign get-help" title="The running sequence of each task in the build"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="The
+ running sequence of each task in the build"></span>
Task order
</dt>
- <dd><a href="{%url "tasks_task" build.pk task.order %}#{{task.order}}">{{task.order}}</a></dd>
+ <dd><a href="{%url "tasks" build.pk %}?page={{task_in_tasks_table_pg}}&limit=25#task-{{task.order}}">{{task.order}}</a></dd>
{% if task.task_executed %}
<dt>
- <i class="icon-question-sign get-help" title="Indicates if this task executes a Python or Shell function(s)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help"
+ title="Indicates if this task executes a Python or Shell
+ function(s)"></span>
Task script type
</dt>
<dd>{{task.get_script_type_display}}</dd>
@@ -211,29 +271,31 @@
<dd><code>{{task.source_url}}</code></dd>
-->
<dt>
- <i class="icon-question-sign get-help" title="Task dependency chain (i.e. other tasks)"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Task dependency chain
+ (i.e. other tasks)"></span>
Dependencies
</dt>
<dd>
- <ul>
- {% for dep in deps %}
- <li><a href="{%url 'task' dep.build.pk dep.pk%}" class="task-info" title="{{dep.get_executed_display}} | {{dep.get_outcome_display}}">{{dep.recipe.name}}_{{dep.recipe.version}} <span class="task-name">{{dep.task_name}}</span></a></li>
- {% empty %}
- <li class="muted">This task has no dependencies</li>
- {% endfor %}
+ <ul class="list-unstyled">
+ {% for dep in deps %}
+ <li><a href="{%url 'task' dep.build.pk dep.pk%}" class="task-info" title="{{dep.get_executed_display}} | {{dep.get_outcome_display}}">{{dep.recipe.name}}_{{dep.recipe.version}} <span class="task-name">{{dep.task_name}}</span></a></li>
+ {% empty %}
+ <li class="text-muted" style="margin-bottom: -10px;">This task has no dependencies</li>
+ {% endfor %}
</ul>
</dd>
<dt>
- <i class="icon-question-sign get-help" title="Tasks that depend on this task"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Tasks that depend on this
+ task"></span>
Reverse dependencies
</dt>
<dd>
- <ul>
- {% for dep in rdeps %}
- <li><a href="{%url 'task' dep.build.pk dep.pk%}" class="task-info" title="{{dep.get_executed_display}} | {{dep.get_outcome_display}}">{{dep.recipe.name}}_{{dep.recipe.version}} <span class="task-name">{{dep.task_name}}</span></a></li>
- {% empty %}
- <li class="muted">This task has no reverse dependencies</li>
- {% endfor %}
+ <ul class="list-unstyled">
+ {% for dep in rdeps %}
+ <li><a href="{%url 'task' dep.build.pk dep.pk%}" class="task-info" title="{{dep.get_executed_display}} | {{dep.get_outcome_display}}">{{dep.recipe.name}}_{{dep.recipe.version}} <span class="task-name">{{dep.task_name}}</span></a></li>
+ {% empty %}
+ <li class="text-muted">This task has no reverse dependencies</li>
+ {% endfor %}
</ul>
</dl>
@@ -244,28 +306,36 @@
<dl class="dl-horizontal">
{% if task.elapsed_time %}
<dt>
- <i class="icon-question-sign get-help" title="How long it took the task to finish in seconds"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="How
+ long it took the task to finish in seconds"></span>
Time (secs)
</dt>
<dd>{{task.elapsed_time|format_none_and_zero|floatformat:2}}</dd>
{% endif %}
{% if task.cpu_time_user > 0 %}
<dt>
- <i class="icon-question-sign get-help" title="Total amount of time spent executing in user mode, in seconds. Note that this time can be greater than the task time due to parallel execution."></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Total amount of time
+ spent executing in user mode, in seconds. Note that this time
+ can be greater than the task time due to parallel
+ execution."></span>
User CPU time (secs)
</dt>
<dd>{{task.cpu_time_user|format_none_and_zero|floatformat:2}}</dd>
{% endif %}
{% if task.cpu_time_system > 0 %}
<dt>
- <i class="icon-question-sign get-help" title="Total amount of time spent executing in kernel mode, in seconds. Note that this time can be greater than the task time due to parallel execution."></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Total amount of time
+ spent executing in kernel mode, in seconds. Note that this time
+ can be greater than the task time due to parallel
+ execution."></span>
System CPU time (secs)
</dt>
<dd>{{task.cpu_time_system|format_none_and_zero|floatformat:2}}</dd>
{% endif %}
{% if task.disk_io > 0 %}
<dt>
- <i class="icon-question-sign get-help" title="Number of bytes written to and read from the disk during the task"></i>
+ <span class="glyphicon glyphicon-question-sign get-help" title="Number of bytes
+ written to and read from the disk during the task"></span>
Disk I/O (bytes)
</dt>
<dd>{{task.disk_io|format_none_and_zero|intcomma}}</dd>
@@ -273,5 +343,6 @@
</dl>
</div>
+
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/tasks.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/tasks.html
deleted file mode 100644
index 84bc10386..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/tasks.html
+++ /dev/null
@@ -1,143 +0,0 @@
-{% extends "basebuildpage.html" %}
-{% load humanize %}
-{% load projecttags %}
-
-{% block title %} {{mainheading}} - {{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}} - {{build.project.name}} - Toaster{% endblock %}
-{% block localbreadcrumb %}
-<li>{{mainheading}}</li>
-{% endblock %}
-
-{% block nav-tasks %}
- {% if 'Tasks' == mainheading %}
- <li class="active"><a href="{% url 'tasks' build.pk %}">Tasks</a></li>
- {% else %}
- <li><a href="{% url 'tasks' build.pk %}">Tasks</a></li>
- {% endif %}
-{% endblock %}
-{% block nav-buildtime %}
- {% if 'Time' == mainheading %}
- <li class="active"><a href="{% url 'buildtime' build.pk %}">Time</a></li>
- {% else %}
- <li><a href="{% url 'buildtime' build.pk %}">Time</a></li>
- {% endif %}
-{% endblock %}
-
-{% block nav-cputime %}
- {% if 'CPU time' == mainheading %}
- <li class="active"><a href="{% url 'cputime' build.pk %}">CPU time</a></li>
- {% else %}
- <li><a href="{% url 'cputime' build.pk %}">CPU time</a></li>
- {% endif %}
-{% endblock %}
-
-{% block nav-diskio %}
- {% if 'Disk I/O' == mainheading %}
- <li class="active"><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li>
- {% else %}
- <li><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li>
- {% endif %}
-{% endblock %}
-
-{% block buildinfomain %}
-<div class="span10">
-{% if not request.GET.filter and not request.GET.search and not objects.paginator.count %}
- <!-- Empty - no data in database -->
- <div class="page-header">
- <h1>{{mainheading}}</h1>
- </div>
- <div class="alert alert-info lead">
- No data was recorded for this build.
- </div>
-
-{% else %}
-
- <div class="page-header">
- <h1>
- {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %}
- {{objects.paginator.count}} task{{objects.paginator.count|pluralize}} found
- {%elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %}
- No tasks found
- {%else%}
- {{mainheading}}
- {%endif%}
- </h1>
- </div>
-
- {% if objects.paginator.count == 0 %}
- <div class="row-fluid">
- <div class="alert">
- <form class="no-results input-append" id="searchform">
- <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %}
- <button class="btn" type="submit" value="Search">Search</button>
- <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all tasks</button>
- </form>
- </div>
- </div>
-
-
- {% else %}
- {% include "basetable_top.html" %}
-
- {% for task in objects %}
- <tr {{ task|task_color }} id="{{task.order}}">
- <td class="order">
- <a href="{%url "task" build.pk task.pk%}">{{task.order}}</a>
- </td>
- <td class="recipe_name" >
- <a href="{% url "recipe" build.pk task.recipe.pk %}">{{task.recipe.name}}</a>
- </td>
- <td class="recipe_version">
- <a href="{% url "recipe" build.pk task.recipe.pk %}">{{task.recipe.version}}</a>
- </td>
- <td class="task_name">
- <a href="{%url "task" build.pk task.pk%}">{{task.task_name}}</a> {% if task.get_description %}<i class="icon-question-sign get-help hover-help" title="{{task.get_description}}"></i> {% endif %}
- </td>
- <td class="executed">
- <a href="{%url "task" build.pk task.pk%}">{{task.get_executed_display}}</a>
- </td>
- <td class="outcome">
- <a href="{%url "task" build.pk task.pk%}">{{task.get_outcome_display}} </a>
- {% if task.outcome = task.OUTCOME_FAILED %}
- <a href="{% url 'build_artifact' build.pk "tasklogfile" task.pk %}">
- <i class="icon-download-alt" title="Download task log file"></i>
- </a>
- {% endif %}
- <i class="icon-question-sign get-help hover-help" title="{{task.get_outcome_help}}"></i>
- </td>
- <td class="cache_attempt">
- <a href="{%url "task" build.pk task.pk%}">{{task.get_sstate_result_display|format_none_and_zero}}</a>
- </td>
- <td class="time_taken">
- {{task.elapsed_time|format_none_and_zero|floatformat:2}}
- </td>
- <td class="cpu_time_system">
- {{task.cpu_time_system|format_none_and_zero|floatformat:2}}
- </td>
- <td class="cpu_time_user">
- {{task.cpu_time_user|format_none_and_zero|floatformat:2}}
- </td>
- <td class="disk_io">
- {{task.disk_io|format_none_and_zero|intcomma}}
- </td>
-
- </tr>
- {% endfor %}
-
- {% include "basetable_bottom.html" %}
- {% endif %} {# objects.paginator.count #}
-{% endif %} {# empty #}
-</div>
-
-<script type="text/javascript">
-
- $(document).ready(function() {
- // highlight heading on the column for the field used for ordering
- if (location.href.search('#') > -1) {
- var task_order = location.href.split('#')[1];
- $("#" + task_order).addClass("highlight");
- }
- });
-
-</script>
-
-{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html
index 4d28793bf..25eef52a3 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-filter.html
@@ -1,20 +1,24 @@
<!-- filter modal -->
-<div id="filter-modal-{{table_name}}" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="false">
- <form id="filter-modal-form-{{table_name}}" style="margin-bottom: 0px">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
- <h3 id="filter-modal-title-{{table_name}}">&nbsp;</h3>
- </div>
- <div class="modal-body">
- <p>Show:</p>
- <span id="filter-actions-{{table_name}}"></span>
- </div>
- <div class="modal-footer">
- <button class="btn btn-primary" type="submit" data-role="filter-apply">
+<div id="filter-modal-{{table_name}}" class="modal fade" tabindex="-1" role="dialog" aria-hidden="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
+ <h3 id="filter-modal-title-{{table_name}}">&nbsp;</h3>
+ </div>
+ <div class="modal-body">
+ <form id="filter-modal-form-{{table_name}}" style="margin-bottom: 0px">
+ <p>Show:</p>
+ <span id="filter-actions-{{table_name}}"></span>
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-primary" type="submit" data-role="filter-apply">
Apply
- </button>
+ </button>
+ </div>
+ </form>
</div>
- </form>
+ </div>
</div>
<button id="clear-filter-btn-{{table_name}}" style="display:none"></button>
<!-- end filter modal -->
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-simple.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-simple.html
index 212318bc5..56cd2ce37 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-simple.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable-simple.html
@@ -26,37 +26,38 @@
{% include 'toastertable-filter.html' %}
-<div class="row-fluid" id="no-results-{{table_name}}" style="display:none">
- <div class="alert">
- <form class="no-results input-append">
- <input class="input-xlarge" id="new-search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>
- <a href="#" class="add-on btn remove-search-btn-{{table_name}}" tabindex="-1">
- <i class="icon-remove"></i>
- </a>
- <button class="btn search-submit-{{table_name}}" >Search</button>
- <button class="btn btn-link remove-search-btn-{{table_name}}">Show {{title|lower}}
- </button>
+<div id="no-results-{{table_name}}" style="display:none">
+ <div class="alert alert-warning">
+ <form class="no-results form-inline">
+ <div class="form-group">
+ <div class="btn-group">
+ <input class="form-control" id="new-search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>
+ <span class="remove-search-btn-{{table_name}} glyphicon glyphicon-remove-circle" tabindex="-1"></span>
+ </div>
+ </div>
+ <button class="btn btn-default search-submit-{{table_name}}">Search</button>
+ <button class="btn btn-link remove-search-btn-{{table_name}}">Show all {{title|lower}}</button>
</form>
</div>
</div>
<div id="table-container-{{table_name}}" style="visibility: hidden">
<!-- control header -->
- <div class="row-fluid" id="table-chrome-{{table_name}}">
- <div class="navbar-search input-append pull-left">
-
- <input class="input-xlarge" id="search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>
- <a href="#" style="display:none" class="add-on btn remove-search-btn-{{table_name}}" tabindex="-1">
- <i class="icon-remove"></i>
- </a>
- <button class="btn" id="search-submit-{{table_name}}" >Search</button>
- </div>
-
- <div class="pull-right">
+ <div id="table-chrome-{{table_name}}">
+ <div class="container-fluid detail-page-contols">
+ <form class="navbar-form navbar-left">
+ <div class="form-group">
+ <div class="btn-group">
+ <input class="form-control" id="search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{% if request.GET.search %}{{request.GET.search}}{% endif %}"/>
+ <span href="#" style="display:none" class="remove-search-btn-{{table_name}} glyphicon glyphicon-remove-circle" tabindex="-1"></span>
+ </div>
+ </div>
+ <button class="btn btn-default" id="search-submit-{{table_name}}" >Search</button>
+ </form>
- <div style="display:inline">
- <span class="divider-vertical"></span>
- <span class="help-inline" style="padding-top:5px;">Show rows:</span>
- <select style="margin-top:5px;margin-bottom:0px;" class="pagesize-{{table_name}}">
+ <form class="navbar-form navbar-right">
+ <div class="form-group">
+ <label>Show rows:</label>
+ <select class="form-control pagesize-{{table_name}}">
{% with "10 25 50 100 150" as list%}
{% for i in list.split %}
<option value="{{i}}">{{i}}</option>
@@ -64,31 +65,36 @@
{% endwith %}
</select>
</div>
- </div>
+ </form>
+ </div>
</div>
<!-- The actual table -->
- <table class="table table-bordered table-hover tablesorter" id="{{table_name}}">
- <thead>
- <tr><th></th></tr>
- </thead>
- <tbody></tbody>
- </table>
+ <div class="table-responsive">
+ <table class="table table-bordered table-hover" id="{{table_name}}">
+ <thead>
+ <tr><th></th></tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
<!-- Pagination controls -->
- <div class="pagination pagination-centered" id="pagination-{{table_name}}">
- <ul class="pagination" style="display: block-inline">
+ <div id="pagination-{{table_name}}">
+ <ul class="pagination">
</ul>
- <div class="pull-right">
- <span class="help-inline" style="padding-top:5px;">Show rows:</span>
- <select style="margin-top:5px;margin-bottom:0px;" class="pagesize-{{table_name}}">
- {% with "10 25 50 100 150" as list%}
- {% for i in list.split %}
- <option value="{{i}}">{{i}}</option>
- {% endfor %}
- {% endwith %}
- </select>
- </div>
+ <form class="navbar-form navbar-right">
+ <div class="form-group">
+ <label>Show rows:</label>
+ <select class="form-control pagesize-{{table_name}}">
+ {% with "10 25 50 100 150" as list%}
+ {% for i in list.split %}
+ <option value="{{i}}">{{i}}</option>
+ {% endfor %}
+ {% endwith %}
+ </select>
+ </div>
+ </form>
</div>
</div>
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable.html
index 21c3d36c7..aa148955e 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/toastertable.html
@@ -25,14 +25,20 @@
{% include 'toastertable-filter.html' %}
-<div class="row-fluid" id="no-results-{{table_name}}" style="display:none">
- <div class="alert">
- <form class="no-results input-append">
- <input class="input-xxlarge" id="new-search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{%if request.GET.search %}{{request.GET.search}}{%endif%}"/>
- <a href="#" class="add-on btn remove-search-btn-{{table_name}}" tabindex="-1">
- <i class="icon-remove"></i>
- </a>
- <button class="btn search-submit-{{table_name}}">
+<div class="row-fluid" id="empty-state-{{table_name}}" style="display:none">
+ <div class="alert alert-info">{{empty_state|safe}}</div>
+</div>
+
+<div id="no-results-{{table_name}}" style="display:none">
+ <div class="alert alert-warning">
+ <form class="form-inline">
+ <div class="form-group">
+ <div class="btn-group">
+ <input class="form-control" id="new-search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{%if request.GET.search %}{{request.GET.search}}{%endif%}"/>
+ <span class="remove-search-btn-{{table_name}} glyphicon glyphicon-remove-circle" tabindex="-1"></a>
+ </div>
+ </div>
+ <button class="btn btn-default search-submit-{{table_name}}">
Search
</button>
<button class="btn btn-link show-all-{{table_name}} remove-search-btn-{{table_name}}">
@@ -44,62 +50,76 @@
<div id="table-container-{{table_name}}" style="visibility: hidden">
<!-- control header -->
- <div class="navbar" id="table-chrome-{{table_name}}">
- <div class="navbar-inner">
- <div class="navbar-search input-append pull-left span6">
-
- <input id="search-input-{{table_name}}" name="search" type="text" placeholder="Search {{title|lower}}" value="{%if request.GET.search%}{{request.GET.search}}{%endif%}"/>
- <a href="#" style="display:none" class="add-on btn remove-search-btn-{{table_name}}" tabindex="-1">
- <i class="icon-remove"></i>
- </a>
- <button class="btn" id="search-submit-{{table_name}}" >Search</button>
+ <div class="navbar navbar-default" id="table-chrome-{{table_name}}">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#table-chrome-collapse-{{table_name}}" aria-expanded="false">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
</div>
-
- <div class="pull-right">
- <div class="btn-group">
- <button id="edit-columns-button" class="btn dropdown-toggle" data-toggle="dropdown">Edit columns
+ <div class="collapse navbar-collapse" id="table-chrome-collapse-{{table_name}}">
+ <form class="navbar-form navbar-left">
+ <div class="form-group">
+ <div class="btn-group">
+ <input id="search-input-{{table_name}}" class="form-control" name="search" type="text" placeholder="Search {{title|lower}}" value="{%if request.GET.search%}{{request.GET.search}}{%endif%}"/>
+ <span class="remove-search-btn-{{table_name}} glyphicon glyphicon-remove-circle" tabindex="-1" style="display:none;">
+ </div>
+ </div>
+ <button class="btn btn-default" id="search-submit-{{table_name}}" >Search</button>
+ </form>
+ <form class="navbar-form navbar-right">
+ <div clas="form-group">
+ <label>Show rows:</label>
+ <select class="form-control pagesize-{{table_name}}">
+ {% with "10 25 50 100 150" as list%}
+ {% for i in list.split %}
+ <option value="{{i}}">{{i}}</option>
+ {% endfor %}
+ {% endwith %}
+ </select>
+ </div>
+ </form>
+ <div class="btn-group navbar-right">
+ <button id="edit-columns-button" class="btn btn-default navbar-btn dropdown-toggle" data-toggle="dropdown">Edit columns
<span class="caret"></span>
</button>
<ul class="dropdown-menu editcol">
</ul>
</div>
- <div style="display:inline">
- <span class="divider-vertical"></span>
- <span class="help-inline" style="padding-top:5px;">Show rows:</span>
- <select style="margin-top:5px;margin-bottom:0px;" class="pagesize-{{table_name}}">
- {% with "10 25 50 100 150" as list%}
- {% for i in list.split %}
- <option value="{{i}}">{{i}}</option>
- {% endfor %}
- {% endwith %}
- </select>
- </div>
</div>
</div>
</div>
<!-- The actual table -->
- <table class="table table-bordered table-hover tablesorter" id="{{table_name}}">
- <thead>
- <tr><th></th></tr>
- </thead>
- <tbody></tbody>
- </table>
+ <div class="table-responsive">
+ <table class="table table-bordered table-hover" id="{{table_name}}">
+ <thead>
+ <tr><th></th></tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
<!-- Pagination controls -->
- <div class="pagination pagination-centered" id="pagination-{{table_name}}">
- <ul class="pagination" style="display: block-inline">
+ <div id="pagination-{{table_name}}">
+ <ul class="pagination">
</ul>
- <div class="pull-right">
- <span class="help-inline" style="padding-top:5px;">Show rows:</span>
- <select style="margin-top:5px;margin-bottom:0px;" class="pagesize-{{table_name}}">
- {% with "10 25 50 100 150" as list%}
- {% for i in list.split %}
- <option value="{{i}}">{{i}}</option>
- {% endfor %}
- {% endwith %}
- </select>
- </div>
+ <form class="navbar-form navbar-right">
+ <div class="form-group">
+ <label>Show rows:</label>
+ <select class="form-control pagesize-{{table_name}}">
+ {% with "10 25 50 100 150" as list%}
+ {% for i in list.split %}
+ <option value="{{i}}">{{i}}</option>
+ {% endfor %}
+ {% endwith %}
+ </select>
+ </div>
+ </form>
</div>
-</div>
+
+</div> <!--end table container -->
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/unavailable_artifact.html b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/unavailable_artifact.html
index 2d3d02c2e..fc77e405f 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/unavailable_artifact.html
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templates/unavailable_artifact.html
@@ -6,10 +6,12 @@
{% block title %} Build artifact does not exist - Toaster {% endblock %}
{% block pagecontent %}
- <div class="row-fluid air">
- <div class="alert alert-info span8 lead">
- <p>The build artifact you are trying to download does not exist.</p>
- <p><a href="javascript:window.history.back()">Back to previous page</a></p>
+ <div class="row">
+ <div class="col-md-8">
+ <div class="alert alert-info lead top-air">
+ <p>The build artifact you are trying to download does not exist.</p>
+ <p><a href="javascript:window.history.back()">Back to previous page</a></p>
+ </div>
</div>
</div>
{% endblock %}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/field_values_filter.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/field_values_filter.py
new file mode 100644
index 000000000..5a73af797
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/field_values_filter.py
@@ -0,0 +1,18 @@
+from django import template
+
+register = template.Library()
+
+def field_values(iterable, field):
+ """
+ Convert an iterable of models into a list of strings, one for each model,
+ where the string for each model is the value of the field "field".
+ """
+ objects = []
+
+ if field:
+ for item in iterable:
+ objects.append(getattr(item, field))
+
+ return objects
+
+register.filter('field_values', field_values) \ No newline at end of file
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/projecttags.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
index 75f2261be..b170a1616 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
@@ -90,7 +90,7 @@ def whitespace_space_filter(value, arg):
def divide(value, arg):
if int(arg) == 0:
return -1
- return int(value) / int(arg)
+ return int(value) // int(arg)
@register.filter
def multiply(value, arg):
@@ -112,11 +112,11 @@ def task_color(task_object, show_green=False):
show_green argument should be True to get green color.
"""
if not task_object.task_executed:
- return 'class=muted'
+ return 'class=text-muted'
elif task_object.outcome == task_object.OUTCOME_FAILED:
- return 'class=error'
+ return 'class=text-danger'
elif task_object.outcome == task_object.OUTCOME_SUCCESS and show_green:
- return 'class=green'
+ return 'class=text-success'
else:
return ''
@@ -250,15 +250,15 @@ from django.utils.safestring import mark_safe
@register.filter
def format_vpackage_rowclass(size):
if size == -1:
- return mark_safe('class="muted"')
+ return mark_safe('class="text-muted"')
return ''
@register.filter
def format_vpackage_namehelp(name):
r = name + '&nbsp;'
- r += '<i class="icon-question-sign get-help hover-help"'
+ r += '<span class="glyphicon glyphicon-question-sign get-help hover-help"'
r += ' title = "' + name + ' has not been built">'
- r += '</i>'
+ r += '</span>'
return mark_safe(r)
@register.filter
@@ -271,14 +271,6 @@ def get_dict_value(dictionary, key):
return ''
@register.filter
-def format_build_date(completed_on):
- now = timezone.now()
- delta = now - completed_on
-
- if delta.days >= 1:
- return True
-
-@register.filter
def is_shaid(text):
""" return True if text length is 40 characters and all hex-digits
"""
@@ -297,3 +289,11 @@ def cut_path_prefix(fullpath, prefixes):
if fullpath.startswith(prefix):
return relpath(fullpath, prefix)
return fullpath
+
+
+@register.filter
+def for_target(package_dependencies, target):
+ """ filter the dependencies to be displayed by the supplied target
+ if no dependences are found for the target then return the predicted
+ dependences"""
+ return package_dependencies.for_target_or_none(target)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tests.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tests.py
index a4cab5848..2b5894f74 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tests.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tests.py
@@ -25,12 +25,13 @@ from django.test import TestCase
from django.test.client import RequestFactory
from django.core.urlresolvers import reverse
from django.utils import timezone
+from django.db.models import Q
from orm.models import Project, Release, BitbakeVersion, Package, LogMessage
-from orm.models import ReleaseLayerSourcePriority, LayerSource, Layer, Build
+from orm.models import LayerSource, Layer, Build
from orm.models import Layer_Version, Recipe, Machine, ProjectLayer, Target
from orm.models import CustomImageRecipe, ProjectVariable
-from orm.models import Branch, CustomImagePackage
+from orm.models import CustomImagePackage
import toastermain
import inspect
@@ -57,7 +58,6 @@ class ViewTests(TestCase):
self.project = Project.objects.first()
self.recipe1 = Recipe.objects.get(pk=2)
- self.recipe2 = Recipe.objects.last()
self.customr = CustomImageRecipe.objects.first()
self.cust_package = CustomImagePackage.objects.first()
self.package = Package.objects.first()
@@ -77,14 +77,18 @@ class ViewTests(TestCase):
self.assertEqual(response.status_code, 200)
self.assertTrue(response['Content-Type'].startswith('application/json'))
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertTrue("error" in data)
self.assertEqual(data["error"], "ok")
self.assertTrue("rows" in data)
- self.assertTrue(self.project.name in [x["name"] for x in data["rows"]])
- self.assertTrue("id" in data["rows"][0])
+ name_found = False
+ for row in data["rows"]:
+ name_found = row['name'].find(self.project.name)
+
+ self.assertTrue(name_found,
+ "project name not found in projects table")
def test_typeaheads(self):
"""Test typeahead ReST API"""
@@ -102,7 +106,7 @@ class ViewTests(TestCase):
self.assertEqual(response.status_code, 200)
self.assertTrue(response['Content-Type'].startswith('application/json'))
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertTrue("error" in data)
self.assertEqual(data["error"], "ok")
@@ -145,34 +149,34 @@ class ViewTests(TestCase):
def test_xhr_import_layer(self):
"""Test xhr_importlayer API"""
- LayerSource.objects.create(sourcetype=LayerSource.TYPE_IMPORTED)
#Test for importing an already existing layer
args = {'vcs_url' : "git://git.example.com/test",
'name' : "base-layer",
'git_ref': "c12b9596afd236116b25ce26dbe0d793de9dc7ce",
'project_id': self.project.id,
+ 'local_source_dir': "",
'dir_path' : "/path/in/repository"}
response = self.client.post(reverse('xhr_importlayer'), args)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertEqual(response.status_code, 200)
self.assertEqual(data["error"], "ok")
#Test to verify import of a layer successful
args['name'] = "meta-oe"
response = self.client.post(reverse('xhr_importlayer'), args)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertTrue(data["error"], "ok")
#Test for html tag in the data
args['<'] = "testing html tag"
response = self.client.post(reverse('xhr_importlayer'), args)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertNotEqual(data["error"], "ok")
#Empty data passed
args = {}
response = self.client.post(reverse('xhr_importlayer'), args)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertNotEqual(data["error"], "ok")
def test_custom_ok(self):
@@ -182,7 +186,7 @@ class ViewTests(TestCase):
'base': self.recipe1.id}
response = self.client.post(url, params)
self.assertEqual(response.status_code, 200)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertEqual(data['error'], 'ok')
self.assertTrue('url' in data)
# get recipe from the database
@@ -198,7 +202,7 @@ class ViewTests(TestCase):
{'name': 'custom', 'project': self.project.id}]:
response = self.client.post(url, params)
self.assertEqual(response.status_code, 200)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertNotEqual(data["error"], "ok")
def test_xhr_custom_wrong_project(self):
@@ -207,7 +211,7 @@ class ViewTests(TestCase):
params = {'name': 'custom', 'project': 0, "base": self.recipe1.id}
response = self.client.post(url, params)
self.assertEqual(response.status_code, 200)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertNotEqual(data["error"], "ok")
def test_xhr_custom_wrong_base(self):
@@ -216,7 +220,7 @@ class ViewTests(TestCase):
params = {'name': 'custom', 'project': self.project.id, "base": 0}
response = self.client.post(url, params)
self.assertEqual(response.status_code, 200)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
self.assertNotEqual(data["error"], "ok")
def test_xhr_custom_details(self):
@@ -231,7 +235,7 @@ class ViewTests(TestCase):
'project_id': self.project.id,
}
}
- self.assertEqual(json.loads(response.content), expected)
+ self.assertEqual(json.loads(response.content.decode('utf-8')), expected)
def test_xhr_custom_del(self):
"""Test deleting custom recipe"""
@@ -244,12 +248,18 @@ class ViewTests(TestCase):
url = reverse('xhr_customrecipe_id', args=(recipe.id,))
response = self.client.delete(url)
self.assertEqual(response.status_code, 200)
- self.assertEqual(json.loads(response.content), {"error": "ok"})
+
+ gotoUrl = reverse('projectcustomimages', args=(self.project.pk,))
+
+ self.assertEqual(json.loads(response.content.decode('utf-8')),
+ {"error": "ok",
+ "gotoUrl": gotoUrl})
+
# try to delete not-existent recipe
url = reverse('xhr_customrecipe_id', args=(recipe.id,))
response = self.client.delete(url)
self.assertEqual(response.status_code, 200)
- self.assertNotEqual(json.loads(response.content)["error"], "ok")
+ self.assertNotEqual(json.loads(response.content.decode('utf-8'))["error"], "ok")
def test_xhr_custom_packages(self):
"""Test adding and deleting package to a custom recipe"""
@@ -259,7 +269,7 @@ class ViewTests(TestCase):
self.cust_package.id)))
self.assertEqual(response.status_code, 200)
- self.assertEqual(json.loads(response.content),
+ self.assertEqual(json.loads(response.content.decode('utf-8')),
{"error": "ok"})
self.assertEqual(self.customr.appends_set.first().name,
self.cust_package.name)
@@ -270,7 +280,7 @@ class ViewTests(TestCase):
response = self.client.delete(del_url)
self.assertEqual(response.status_code, 200)
- self.assertEqual(json.loads(response.content), {"error": "ok"})
+ self.assertEqual(json.loads(response.content.decode('utf-8')), {"error": "ok"})
all_packages = self.customr.get_all_packages().values_list('pk',
flat=True)
@@ -282,7 +292,7 @@ class ViewTests(TestCase):
response = self.client.delete(del_url)
self.assertEqual(response.status_code, 200)
- self.assertNotEqual(json.loads(response.content)["error"], "ok")
+ self.assertNotEqual(json.loads(response.content.decode('utf-8'))["error"], "ok")
def test_xhr_custom_packages_err(self):
"""Test error conditions of xhr_customrecipe_packages"""
@@ -293,51 +303,60 @@ class ViewTests(TestCase):
for method in (self.client.put, self.client.delete):
response = method(url)
self.assertEqual(response.status_code, 200)
- self.assertNotEqual(json.loads(response.content),
+ self.assertNotEqual(json.loads(response.content.decode('utf-8')),
{"error": "ok"})
def test_download_custom_recipe(self):
"""Download the recipe file generated for the custom image"""
# Create a dummy recipe file for the custom image generation to read
- open("/tmp/a_recipe.bb", 'wa').close()
+ open("/tmp/a_recipe.bb", 'a').close()
response = self.client.get(reverse('customrecipedownload',
args=(self.project.id,
self.customr.id)))
self.assertEqual(response.status_code, 200)
-
def test_software_recipes_table(self):
"""Test structure returned for Software RecipesTable"""
table = SoftwareRecipesTable()
request = RequestFactory().get('/foo/', {'format': 'json'})
response = table.get(request, pid=self.project.id)
- data = json.loads(response.content)
+ data = json.loads(response.content.decode('utf-8'))
+
+ recipes = Recipe.objects.filter(Q(is_image=False))
+ self.assertTrue(len(recipes) > 1,
+ "Need more than one software recipe to test "
+ "SoftwareRecipesTable")
+
+ recipe1 = recipes[0]
+ recipe2 = recipes[1]
rows = data['rows']
- row1 = next(x for x in rows if x['name'] == self.recipe1.name)
- row2 = next(x for x in rows if x['name'] == self.recipe2.name)
+ row1 = next(x for x in rows if x['name'] == recipe1.name)
+ row2 = next(x for x in rows if x['name'] == recipe2.name)
self.assertEqual(response.status_code, 200, 'should be 200 OK status')
# check other columns have been populated correctly
- self.assertEqual(row1['name'], self.recipe1.name)
- self.assertEqual(row1['version'], self.recipe1.version)
- self.assertEqual(row1['get_description_or_summary'],
- self.recipe1.description)
- self.assertEqual(row1['layer_version__layer__name'],
- self.recipe1.layer_version.layer.name)
- self.assertEqual(row2['name'], self.recipe2.name)
- self.assertEqual(row2['version'], self.recipe2.version)
- self.assertEqual(row2['get_description_or_summary'],
- self.recipe2.description)
- self.assertEqual(row2['layer_version__layer__name'],
- self.recipe2.layer_version.layer.name)
+ self.assertTrue(recipe1.name in row1['name'])
+ self.assertTrue(recipe1.version in row1['version'])
+ self.assertTrue(recipe1.description in
+ row1['get_description_or_summary'])
+
+ self.assertTrue(recipe1.layer_version.layer.name in
+ row1['layer_version__layer__name'])
+
+ self.assertTrue(recipe2.name in row2['name'])
+ self.assertTrue(recipe2.version in row2['version'])
+ self.assertTrue(recipe2.description in
+ row2['get_description_or_summary'])
+
+ self.assertTrue(recipe2.layer_version.layer.name in
+ row2['layer_version__layer__name'])
def test_toaster_tables(self):
"""Test all ToasterTables instances"""
- current_recipes = self.project.get_available_recipes()
def get_data(table, options={}):
"""Send a request and parse the json response"""
@@ -354,19 +373,36 @@ class ViewTests(TestCase):
'layerid': self.lver.pk,
'recipeid': self.recipe1.pk,
'recipe_id': image_recipe.pk,
- 'custrecipeid': self.customr.pk
- }
+ 'custrecipeid': self.customr.pk,
+ 'build_id': 1,
+ 'target_id': 1}
response = table.get(request, **args)
- return json.loads(response.content)
+ return json.loads(response.content.decode('utf-8'))
+
+ def get_text_from_td(td):
+ """If we have html in the td then extract the text portion"""
+ # just so we don't waste time parsing non html
+ if "<" not in td:
+ ret = td
+ else:
+ ret = BeautifulSoup(td, "html.parser").text
+
+ if len(ret):
+ return "0"
+ else:
+ return ret
# Get a list of classes in tables module
tables = inspect.getmembers(toastergui.tables, inspect.isclass)
+ tables.extend(inspect.getmembers(toastergui.buildtables,
+ inspect.isclass))
for name, table_cls in tables:
# Filter out the non ToasterTables from the tables module
if not issubclass(table_cls, toastergui.widgets.ToasterTable) or \
- table_cls == toastergui.widgets.ToasterTable:
+ table_cls == toastergui.widgets.ToasterTable or \
+ 'Mixin' in name:
continue
# Get the table data without any options, this also does the
@@ -379,8 +415,10 @@ class ViewTests(TestCase):
"Cannot test on a %s table with < 1 row" % name)
if table.default_orderby:
- row_one = all_data['rows'][0][table.default_orderby.strip("-")]
- row_two = all_data['rows'][1][table.default_orderby.strip("-")]
+ row_one = get_text_from_td(
+ all_data['rows'][0][table.default_orderby.strip("-")])
+ row_two = get_text_from_td(
+ all_data['rows'][1][table.default_orderby.strip("-")])
if '-' in table.default_orderby:
self.assertTrue(row_one >= row_two,
@@ -399,28 +437,36 @@ class ViewTests(TestCase):
# If a column is orderable test it in both order
# directions ordering on the columns field_name
ascending = get_data(table_cls(),
- {"orderby" : column['field_name']})
+ {"orderby": column['field_name']})
- row_one = ascending['rows'][0][column['field_name']]
- row_two = ascending['rows'][1][column['field_name']]
+ row_one = get_text_from_td(
+ ascending['rows'][0][column['field_name']])
+ row_two = get_text_from_td(
+ ascending['rows'][1][column['field_name']])
self.assertTrue(row_one <= row_two,
- "Ascending sort applied but row 0 is less "
- "than row 1 %s %s " %
- (column['field_name'], name))
-
+ "Ascending sort applied but row 0: \"%s\""
+ " is less than row 1: \"%s\" "
+ "%s %s " %
+ (row_one, row_two,
+ column['field_name'], name))
descending = get_data(table_cls(),
- {"orderby" :
+ {"orderby":
'-'+column['field_name']})
- row_one = descending['rows'][0][column['field_name']]
- row_two = descending['rows'][1][column['field_name']]
+ row_one = get_text_from_td(
+ descending['rows'][0][column['field_name']])
+ row_two = get_text_from_td(
+ descending['rows'][1][column['field_name']])
self.assertTrue(row_one >= row_two,
- "Descending sort applied but row 0 is "
- "greater than row 1 %s %s" %
- (column['field_name'], name))
+ "Descending sort applied but row 0: %s"
+ "is greater than row 1: %s"
+ "field %s table %s" %
+ (row_one,
+ row_two,
+ column['field_name'], name))
# If the two start rows are the same we haven't actually
# changed the order
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/typeaheads.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/typeaheads.py
index dd4b7f505..4ded9ac2e 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/typeaheads.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/typeaheads.py
@@ -55,6 +55,7 @@ class LayersTypeAhead(ToasterTypeAhead):
'vcs_url' : layer_version.layer.vcs_url,
'vcs_reference' : vcs_reference,
'detail' : detail,
+ 'local_source_dir' : layer_version.layer.local_source_dir,
}
results.append(needed_fields)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/urls.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/urls.py
index 27b0baabf..ece9ac169 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/urls.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/urls.py
@@ -21,8 +21,10 @@ from django.views.generic import RedirectView, TemplateView
from django.http import HttpResponseBadRequest
from toastergui import tables
+from toastergui import buildtables
from toastergui import typeaheads
from toastergui import api
+from toastergui import widgets
urlpatterns = patterns('toastergui.views',
# landing page
@@ -34,17 +36,28 @@ urlpatterns = patterns('toastergui.views',
# build info navigation
url(r'^build/(?P<build_id>\d+)$', 'builddashboard', name="builddashboard"),
+ url(r'^build/(?P<build_id>\d+)/tasks/$',
+ buildtables.BuildTasksTable.as_view(
+ template_name="buildinfo-toastertable.html"),
+ name='tasks'),
- url(r'^build/(?P<build_id>\d+)/tasks/$', 'tasks', name='tasks'),
- url(r'^build/(?P<build_id>\d+)/tasks/(?P<task_id>\d+)/$', 'tasks_task', name='tasks_task'),
url(r'^build/(?P<build_id>\d+)/task/(?P<task_id>\d+)$', 'task', name='task'),
- url(r'^build/(?P<build_id>\d+)/recipes/$', 'recipes', name='recipes'),
+ url(r'^build/(?P<build_id>\d+)/recipes/$',
+ buildtables.BuiltRecipesTable.as_view(
+ template_name="buildinfo-toastertable.html"),
+ name='recipes'),
+
url(r'^build/(?P<build_id>\d+)/recipe/(?P<recipe_id>\d+)/active_tab/(?P<active_tab>\d{1})$', 'recipe', name='recipe'),
+
url(r'^build/(?P<build_id>\d+)/recipe/(?P<recipe_id>\d+)$', 'recipe', name='recipe'),
url(r'^build/(?P<build_id>\d+)/recipe_packages/(?P<recipe_id>\d+)$', 'recipe_packages', name='recipe_packages'),
- url(r'^build/(?P<build_id>\d+)/packages/$', 'bpackage', name='packages'),
+ url(r'^build/(?P<build_id>\d+)/packages/$',
+ buildtables.BuiltPackagesTable.as_view(
+ template_name="buildinfo-toastertable.html"),
+ name='packages'),
+
url(r'^build/(?P<build_id>\d+)/package/(?P<package_id>\d+)$', 'package_built_detail',
name='package_built_detail'),
url(r'^build/(?P<build_id>\d+)/package_built_dependencies/(?P<package_id>\d+)$',
@@ -56,17 +69,31 @@ urlpatterns = patterns('toastergui.views',
url(r'^build/(?P<build_id>\d+)/package_included_reverse_dependencies/(?P<target_id>\d+)/(?P<package_id>\d+)$',
'package_included_reverse_dependencies', name='package_included_reverse_dependencies'),
- # images are known as targets in the internal model
- url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$', 'target', name='target'),
- url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/targetpkg$', 'targetpkg', name='targetpkg'),
+ url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$',
+ buildtables.InstalledPackagesTable.as_view(
+ template_name="target.html"),
+ name='target'),
+
+
url(r'^dentries/build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$', 'xhr_dirinfo', name='dirinfo_ajax'),
url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/dirinfo$', 'dirinfo', name='dirinfo'),
url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/dirinfo_filepath/_(?P<file_path>(?:/[^/\n]+)*)$', 'dirinfo', name='dirinfo_filepath'),
url(r'^build/(?P<build_id>\d+)/configuration$', 'configuration', name='configuration'),
url(r'^build/(?P<build_id>\d+)/configvars$', 'configvars', name='configvars'),
- url(r'^build/(?P<build_id>\d+)/buildtime$', 'buildtime', name='buildtime'),
- url(r'^build/(?P<build_id>\d+)/cputime$', 'cputime', name='cputime'),
- url(r'^build/(?P<build_id>\d+)/diskio$', 'diskio', name='diskio'),
+ url(r'^build/(?P<build_id>\d+)/buildtime$',
+ buildtables.BuildTimeTable.as_view(
+ template_name="buildinfo-toastertable.html"),
+ name='buildtime'),
+
+ url(r'^build/(?P<build_id>\d+)/cputime$',
+ buildtables.BuildCPUTimeTable.as_view(
+ template_name="buildinfo-toastertable.html"),
+ name='cputime'),
+
+ url(r'^build/(?P<build_id>\d+)/diskio$',
+ buildtables.BuildIOTable.as_view(
+ template_name="buildinfo-toastertable.html"),
+ name='diskio'),
# image information dir
url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/packagefile/(?P<packagefile_id>\d+)$',
@@ -164,27 +191,47 @@ urlpatterns = patterns('toastergui.views',
name='xhr_configvaredit'),
url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'),
- url(r'^xhr_updatelayer/$', 'xhr_updatelayer', name='xhr_updatelayer'),
+
+ url(r'^xhr_layer/(?P<pid>\d+)/(?P<layerversion_id>\d+)$',
+ api.XhrLayer.as_view(),
+ name='xhr_layer'),
# JS Unit tests
url(r'^js-unit-tests/$', 'jsunittests', name='js-unit-tests'),
# image customisation functionality
- url(r'^xhr_customrecipe/(?P<recipe_id>\d+)/packages/(?P<package_id>\d+|)$',
- 'xhr_customrecipe_packages', name='xhr_customrecipe_packages'),
+ url(r'^xhr_customrecipe/(?P<recipe_id>\d+)'
+ '/packages/(?P<package_id>\d+|)$',
+ api.XhrCustomRecipePackages.as_view(),
+ name='xhr_customrecipe_packages'),
url(r'^xhr_customrecipe/(?P<recipe_id>\d+)/packages/$',
- 'xhr_customrecipe_packages', name='xhr_customrecipe_packages'),
+ api.XhrCustomRecipePackages.as_view(),
+ name='xhr_customrecipe_packages'),
- url(r'^xhr_customrecipe/(?P<recipe_id>\d+)$', 'xhr_customrecipe_id',
+ url(r'^xhr_customrecipe/(?P<recipe_id>\d+)$',
+ api.XhrCustomRecipeId.as_view(),
name='xhr_customrecipe_id'),
- url(r'^xhr_customrecipe/', 'xhr_customrecipe',
+
+ url(r'^xhr_customrecipe/',
+ api.XhrCustomRecipe.as_view(),
name='xhr_customrecipe'),
url(r'^xhr_buildrequest/project/(?P<pid>\d+)$',
- api.XhrBuildRequest.as_view(),
+ api.XhrBuildRequest.as_view(),
name='xhr_buildrequest'),
+ url(r'xhr_project/(?P<project_id>\d+)$',
+ api.XhrProject.as_view(),
+ name='xhr_project'),
+
+ url(r'xhr_build/(?P<build_id>\d+)$',
+ api.XhrBuild.as_view(),
+ name='xhr_build'),
+
+ url(r'^mostrecentbuilds$', widgets.MostRecentBuildsView.as_view(),
+ name='most_recent_builds'),
+
# default redirection
url(r'^$', RedirectView.as_view(url='landing', permanent=True)),
)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/views.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/views.py
index bd5bf6334..2efb0fd56 100755
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/views.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/views.py
@@ -19,42 +19,37 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-# pylint: disable=method-hidden
-# Gives E:848, 4: An attribute defined in json.encoder line 162 hides this method (method-hidden)
-# which is an invalid warning
-import operator,re
+import re
-from django.db.models import F, Q, Sum, Count, Max
-from django.db import IntegrityError, Error
+from django.db.models import F, Q, Sum
+from django.db import IntegrityError
from django.shortcuts import render, redirect, get_object_or_404
-from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable
-from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency
-from orm.models import Target_Installed_Package, Target_File, Target_Image_File, BuildArtifact, CustomImagePackage
+from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe
+from orm.models import LogMessage, Variable, Package_Dependency, Package
+from orm.models import Task_Dependency, Package_File
+from orm.models import Target_Installed_Package, Target_File
+from orm.models import TargetKernelFile, TargetSDKFile, Target_Image_File
from orm.models import BitbakeVersion, CustomImageRecipe
-from bldcontrol import bbcontroller
-from django.views.decorators.cache import cache_control
+
from django.core.urlresolvers import reverse, resolve
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
-from django.http import HttpResponseBadRequest, HttpResponseNotFound
+from django.http import HttpResponseNotFound
from django.utils import timezone
-from django.utils.html import escape
from datetime import timedelta, datetime
-from django.utils import formats
from toastergui.templatetags.projecttags import json as jsonfilter
from decimal import Decimal
import json
import os
from os.path import dirname
-from functools import wraps
-import itertools
import mimetypes
import logging
logger = logging.getLogger("toaster")
+
class MimeTypeFinder(object):
# setting this to False enables additional non-standard mimetypes
# to be included in the guess
@@ -160,7 +155,7 @@ def _lv_to_dict(prj, x = None):
return {"id": x.pk,
"name": x.layer.name,
"tooltip": "%s | %s" % (x.layer.vcs_url,x.get_vcs_reference()),
- "detail": "(%s" % x.layer.vcs_url + (")" if x.up_branch == None else " | "+x.get_vcs_reference()+")"),
+ "detail": "(%s" % x.layer.vcs_url + (")" if x.release == None else " | "+x.get_vcs_reference()+")"),
"giturl": x.layer.vcs_url,
"layerdetailurl" : reverse('layerdetails', args=(prj.id,x.pk)),
"revision" : x.get_vcs_reference(),
@@ -200,16 +195,19 @@ def _verify_parameters(g, mandatory_parameters):
return None
def _redirect_parameters(view, g, mandatory_parameters, *args, **kwargs):
- import urllib
+ try:
+ from urllib import unquote, urlencode
+ except ImportError:
+ from urllib.parse import unquote, urlencode
url = reverse(view, kwargs=kwargs)
params = {}
for i in g:
params[i] = g[i]
for i in mandatory_parameters:
if not i in params:
- params[i] = urllib.unquote(str(mandatory_parameters[i]))
+ params[i] = unquote(str(mandatory_parameters[i]))
- return redirect(url + "?%s" % urllib.urlencode(params), permanent = False, **kwargs)
+ return redirect(url + "?%s" % urlencode(params), permanent = False, **kwargs)
class RedirectException(Exception):
def __init__(self, view, g, mandatory_parameters, *args, **kwargs):
@@ -229,10 +227,18 @@ OR_VALUE_SEPARATOR = "|"
DESCENDING = "-"
def __get_q_for_val(name, value):
- if "OR" in value:
- return reduce(operator.or_, map(lambda x: __get_q_for_val(name, x), [ x for x in value.split("OR") ]))
+ if "OR" in value or "AND" in value:
+ result = None
+ for x in value.split("OR"):
+ x = __get_q_for_val(name, x)
+ result = result | x if result else x
+ return result
if "AND" in value:
- return reduce(operator.and_, map(lambda x: __get_q_for_val(name, x), [ x for x in value.split("AND") ]))
+ result = None
+ for x in value.split("AND"):
+ x = __get_q_for_val(name, x)
+ result = result & x if result else x
+ return result
if value.startswith("NOT"):
value = value[3:]
if value == 'None':
@@ -251,14 +257,18 @@ def _get_filtering_query(filter_string):
and_keys = search_terms[0].split(AND_VALUE_SEPARATOR)
and_values = search_terms[1].split(AND_VALUE_SEPARATOR)
- and_query = []
+ and_query = None
for kv in zip(and_keys, and_values):
or_keys = kv[0].split(OR_VALUE_SEPARATOR)
or_values = kv[1].split(OR_VALUE_SEPARATOR)
- querydict = dict(zip(or_keys, or_values))
- and_query.append(reduce(operator.or_, map(lambda x: __get_q_for_val(x, querydict[x]), [k for k in querydict])))
+ query = None
+ for key, val in zip(or_keys, or_values):
+ x = __get_q_for_val(key, val)
+ query = query | x if query else x
+
+ and_query = and_query & query if and_query else query
- return reduce(operator.and_, [k for k in and_query])
+ return and_query
def _get_toggle_order(request, orderkey, toggle_reverse = False):
if toggle_reverse:
@@ -295,21 +305,24 @@ def _validate_input(field_input, model):
# Check we are looking for a valid field
valid_fields = model._meta.get_all_field_names()
for field in field_input_list[0].split(AND_VALUE_SEPARATOR):
- if not reduce(lambda x, y: x or y, [ field.startswith(x) for x in valid_fields ]):
- return None, (field, [ x for x in valid_fields ])
+ if True in [field.startswith(x) for x in valid_fields]:
+ break
+ else:
+ return None, (field, valid_fields)
return field_input, invalid
# uses search_allowed_fields in orm/models.py to create a search query
# for these fields with the supplied input text
def _get_search_results(search_term, queryset, model):
- search_objects = []
+ search_object = None
for st in search_term.split(" "):
- q_map = map(lambda x: Q(**{x+'__icontains': st}),
- model.search_allowed_fields)
+ queries = None
+ for field in model.search_allowed_fields:
+ query = Q(**{field + '__icontains': st})
+ queries = queries | query if queries else query
- search_objects.append(reduce(operator.or_, q_map))
- search_object = reduce(operator.and_, search_objects)
+ search_object = search_object & queries if search_object else queries
queryset = queryset.filter(search_object)
return queryset
@@ -452,46 +465,58 @@ def builddashboard( request, build_id ):
recipeCount = Recipe.objects.filter( layer_version__id__in = layerVersionId ).count( );
tgts = Target.objects.filter( build_id = build_id ).order_by( 'target' );
- ##
# set up custom target list with computed package and image data
- #
-
- targets = [ ]
+ targets = []
ntargets = 0
- hasImages = False
- targetHasNoImages = False
+
+ # True if at least one target for this build has an SDK artifact
+ # or image file
+ has_artifacts = False
+
for t in tgts:
- elem = { }
- elem[ 'target' ] = t
- if t.is_image:
- hasImages = True
+ elem = {}
+ elem['target'] = t
+
+ target_has_images = False
+ image_files = []
+
npkg = 0
pkgsz = 0
package = None
for package in Package.objects.filter(id__in = [x.package_id for x in t.target_installed_package_set.all()]):
pkgsz = pkgsz + package.size
- if ( package.installed_name ):
+ if package.installed_name:
npkg = npkg + 1
- elem[ 'npkg' ] = npkg
- elem[ 'pkgsz' ] = pkgsz
- ti = Target_Image_File.objects.filter( target_id = t.id )
- imageFiles = [ ]
+ elem['npkg'] = npkg
+ elem['pkgsz'] = pkgsz
+ ti = Target_Image_File.objects.filter(target_id = t.id)
for i in ti:
- ndx = i.file_name.rfind( '/' )
- if ( ndx < 0 ):
+ ndx = i.file_name.rfind('/')
+ if ndx < 0:
ndx = 0;
- f = i.file_name[ ndx + 1: ]
- imageFiles.append({
+ f = i.file_name[ndx + 1:]
+ image_files.append({
'id': i.id,
'path': f,
'size': i.file_size,
'suffix': i.suffix
})
- if t.is_image and (len(imageFiles) <= 0 or len(t.license_manifest_path) <= 0):
- targetHasNoImages = True
- elem[ 'imageFiles' ] = imageFiles
- elem[ 'targetHasNoImages' ] = targetHasNoImages
- targets.append( elem )
+ if len(image_files) > 0:
+ target_has_images = True
+ elem['targetHasImages'] = target_has_images
+
+ elem['imageFiles'] = image_files
+ elem['target_kernel_artifacts'] = t.targetkernelfile_set.all()
+
+ target_sdk_files = t.targetsdkfile_set.all()
+ target_sdk_artifacts_count = target_sdk_files.count()
+ elem['target_sdk_artifacts_count'] = target_sdk_artifacts_count
+ elem['target_sdk_artifacts'] = target_sdk_files
+
+ if target_has_images or target_sdk_artifacts_count > 0:
+ has_artifacts = True
+
+ targets.append(elem)
##
# how many packages in this build - ignore anonymous ones
@@ -508,7 +533,7 @@ def builddashboard( request, build_id ):
context = {
'build' : build,
'project' : build.project,
- 'hasImages' : hasImages,
+ 'hasArtifacts' : has_artifacts,
'ntargets' : ntargets,
'targets' : targets,
'recipecount' : recipeCount,
@@ -578,6 +603,7 @@ def task( request, build_id, task_id ):
'log_body' : log_body,
'showing_matches' : False,
'uri_list' : uri_list,
+ 'task_in_tasks_table_pg': int(task_object.order / 25) + 1
}
if request.GET.get( 'show_matches', "" ):
context[ 'showing_matches' ] = True
@@ -662,175 +688,6 @@ def recipe_packages(request, build_id, recipe_id):
_set_parameters_values(pagesize, orderby, request)
return response
-def target_common( request, build_id, target_id, variant ):
- template = "target.html"
- default_orderby = 'name:+'
-
- (pagesize, orderby) = _get_parameters_values(request, 25, default_orderby)
- mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby': orderby }
- retval = _verify_parameters( request.GET, mandatory_parameters )
- if retval:
- return _redirect_parameters(
- variant, request.GET, mandatory_parameters,
- build_id = build_id, target_id = target_id )
- ( filter_string, search_term, ordering_string ) = _search_tuple( request, Package )
-
- # FUTURE: get rid of nested sub-queries replacing with ManyToMany field
- queryset = Package.objects.filter(
- size__gte = 0,
- id__in = Target_Installed_Package.objects.filter(
- target_id=target_id ).values( 'package_id' ))
- packages_sum = queryset.aggregate( Sum( 'installed_size' ))
- queryset = _get_queryset(
- Package, queryset, filter_string, search_term, ordering_string, 'name' )
- queryset = queryset.select_related("recipe", "recipe__layer_version", "recipe__layer_version__layer")
- packages = _build_page_range( Paginator(queryset, pagesize), request.GET.get( 'page', 1 ))
-
- build = Build.objects.get( pk = build_id )
-
- # bring in package dependencies
- for p in packages.object_list:
- p.runtime_dependencies = p.package_dependencies_source.filter(
- target_id = target_id, dep_type=Package_Dependency.TYPE_TRDEPENDS ).select_related("depends_on")
- p.reverse_runtime_dependencies = p.package_dependencies_target.filter(
- target_id = target_id, dep_type=Package_Dependency.TYPE_TRDEPENDS ).select_related("package")
- tc_package = {
- 'name' : 'Package',
- 'qhelp' : 'Packaged output resulting from building a recipe included in this image',
- 'orderfield' : _get_toggle_order( request, "name" ),
- 'ordericon' : _get_toggle_order_icon( request, "name" ),
- }
- tc_packageVersion = {
- 'name' : 'Package version',
- 'qhelp' : 'The package version and revision',
- }
- tc_size = {
- 'name' : 'Size',
- 'qhelp' : 'The size of the package',
- 'orderfield' : _get_toggle_order( request, "size", True ),
- 'ordericon' : _get_toggle_order_icon( request, "size" ),
- 'orderkey' : 'size',
- 'clclass' : 'size',
- 'dclass' : 'span2',
- }
- if ( variant == 'target' ):
- tc_size[ "hidden" ] = 0
- else:
- tc_size[ "hidden" ] = 1
- tc_sizePercentage = {
- 'name' : 'Size over total (%)',
- 'qhelp' : 'Proportion of the overall size represented by this package',
- 'clclass' : 'size_over_total',
- 'hidden' : 1,
- }
- tc_license = {
- 'name' : 'License',
- 'qhelp' : 'The license under which the package is distributed. Separate license names u\
-sing | (pipe) means there is a choice between licenses. Separate license names using & (ampersand) m\
-eans multiple licenses exist that cover different parts of the source',
- 'orderfield' : _get_toggle_order( request, "license" ),
- 'ordericon' : _get_toggle_order_icon( request, "license" ),
- 'orderkey' : 'license',
- 'clclass' : 'license',
- }
- if ( variant == 'target' ):
- tc_license[ "hidden" ] = 1
- else:
- tc_license[ "hidden" ] = 0
- tc_dependencies = {
- 'name' : 'Dependencies',
- 'qhelp' : "Package runtime dependencies (other packages)",
- 'clclass' : 'depends',
- }
- if ( variant == 'target' ):
- tc_dependencies[ "hidden" ] = 0
- else:
- tc_dependencies[ "hidden" ] = 1
- tc_rdependencies = {
- 'name' : 'Reverse dependencies',
- 'qhelp' : 'Package run-time reverse dependencies (i.e. which other packages depend on this package',
- 'clclass' : 'brought_in_by',
- }
- if ( variant == 'target' ):
- tc_rdependencies[ "hidden" ] = 0
- else:
- tc_rdependencies[ "hidden" ] = 1
- tc_recipe = {
- 'name' : 'Recipe',
- 'qhelp' : 'The name of the recipe building the package',
- 'orderfield' : _get_toggle_order( request, "recipe__name" ),
- 'ordericon' : _get_toggle_order_icon( request, "recipe__name" ),
- 'orderkey' : "recipe__name",
- 'clclass' : 'recipe_name',
- 'hidden' : 0,
- }
- tc_recipeVersion = {
- 'name' : 'Recipe version',
- 'qhelp' : 'Version and revision of the recipe building the package',
- 'clclass' : 'recipe_version',
- 'hidden' : 1,
- }
- tc_layer = {
- 'name' : 'Layer',
- 'qhelp' : 'The name of the layer providing the recipe that builds the package',
- 'orderfield' : _get_toggle_order( request, "recipe__layer_version__layer__name" ),
- 'ordericon' : _get_toggle_order_icon( request, "recipe__layer_version__layer__name" ),
- 'orderkey' : "recipe__layer_version__layer__name",
- 'clclass' : 'layer_name',
- 'hidden' : 1,
- }
- tc_layerBranch = {
- 'name' : 'Layer branch',
- 'qhelp' : 'The Git branch of the layer providing the recipe that builds the package',
- 'orderfield' : _get_toggle_order( request, "recipe__layer_version__branch" ),
- 'ordericon' : _get_toggle_order_icon( request, "recipe__layer_version__branch" ),
- 'orderkey' : "recipe__layer_version__branch",
- 'clclass' : 'layer_branch',
- 'hidden' : 1,
- }
- tc_layerCommit = {
- 'name' : 'Layer commit',
- 'qhelp' : 'The Git commit of the layer providing the recipe that builds the package',
- 'clclass' : 'layer_commit',
- 'hidden' : 1,
- }
-
- context = {
- 'objectname': variant,
- 'build' : build,
- 'project' : build.project,
- 'target' : Target.objects.filter( pk = target_id )[ 0 ],
- 'objects' : packages,
- 'packages_sum' : packages_sum[ 'installed_size__sum' ],
- 'object_search_display': "packages included",
- 'default_orderby' : default_orderby,
- 'tablecols' : [
- tc_package,
- tc_packageVersion,
- tc_license,
- tc_size,
- tc_sizePercentage,
- tc_dependencies,
- tc_rdependencies,
- tc_recipe,
- tc_recipeVersion,
- tc_layer,
- tc_layerBranch,
- tc_layerCommit,
- ]
- }
-
-
- response = render(request, template, context)
- _set_parameters_values(pagesize, orderby, request)
- return response
-
-def target( request, build_id, target_id ):
- return( target_common( request, build_id, target_id, "target" ))
-
-def targetpkg( request, build_id, target_id ):
- return( target_common( request, build_id, target_id, "targetpkg" ))
-
from django.core.serializers.json import DjangoJSONEncoder
from django.http import HttpResponse
def xhr_dirinfo(request, build_id, target_id):
@@ -910,8 +767,8 @@ def _get_dir_entries(build_id, target_id, start):
response.append(entry)
except Exception as e:
- print "Exception ", e
- traceback.print_exc(e)
+ print("Exception ", e)
+ traceback.print_exc()
# sort by directories first, then by name
rsorted = sorted(response, key=lambda entry : entry['name'])
@@ -952,18 +809,29 @@ def dirinfo(request, build_id, target_id, file_path=None):
return render(request, template, context)
def _find_task_dep(task_object):
- return map(lambda x: x.depends_on, Task_Dependency.objects.filter(task=task_object).filter(depends_on__order__gt = 0).exclude(depends_on__outcome = Task.OUTCOME_NA).select_related("depends_on"))
-
+ tdeps = Task_Dependency.objects.filter(task=task_object).filter(depends_on__order__gt=0)
+ tdeps = tdeps.exclude(depends_on__outcome=Task.OUTCOME_NA).select_related("depends_on")
+ return [x.depends_on for x in tdeps]
def _find_task_revdep(task_object):
- tp = []
- tp = map(lambda t: t.task, Task_Dependency.objects.filter(depends_on=task_object).filter(task__order__gt=0).exclude(task__outcome = Task.OUTCOME_NA).select_related("task", "task__recipe", "task__build"))
- return tp
+ tdeps = Task_Dependency.objects.filter(depends_on=task_object).filter(task__order__gt=0)
+ tdeps = tdeps.exclude(task__outcome = Task.OUTCOME_NA).select_related("task", "task__recipe", "task__build")
+
+ # exclude self-dependencies to prevent infinite dependency loop
+ # in generateCoveredList2()
+ tdeps = tdeps.exclude(task=task_object)
+
+ return [tdep.task for tdep in tdeps]
def _find_task_revdep_list(tasklist):
- tp = []
- tp = map(lambda t: t.task, Task_Dependency.objects.filter(depends_on__in=tasklist).filter(task__order__gt=0).exclude(task__outcome = Task.OUTCOME_NA).select_related("task", "task__recipe", "task__build"))
- return tp
+ tdeps = Task_Dependency.objects.filter(depends_on__in=tasklist).filter(task__order__gt=0)
+ tdeps = tdeps.exclude(task__outcome=Task.OUTCOME_NA).select_related("task", "task__recipe", "task__build")
+
+ # exclude self-dependencies to prevent infinite dependency loop
+ # in generateCoveredList2()
+ tdeps = tdeps.exclude(task=F('depends_on'))
+
+ return [tdep.task for tdep in tdeps]
def _find_task_provider(task_object):
task_revdeps = _find_task_revdep(task_object)
@@ -976,396 +844,6 @@ def _find_task_provider(task_object):
return trc
return None
-def tasks_common(request, build_id, variant, task_anchor):
-# This class is shared between these pages
-#
-# Column tasks buildtime diskio cpuusage
-# --------- ------ ---------- ------- ---------
-# Cache def
-# CPU min -
-# Disk min -
-# Executed def def def def
-# Log
-# Order def +
-# Outcome def def def def
-# Recipe min min min min
-# Version
-# Task min min min min
-# Time min -
-#
-# 'min':on always, 'def':on by default, else hidden
-# '+' default column sort up, '-' default column sort down
-
- anchor = request.GET.get('anchor', '')
- if not anchor:
- anchor=task_anchor
-
- # default ordering depends on variant
- default_orderby = None
- filter_search_display = 'tasks'
-
- if 'buildtime' == variant:
- default_orderby = 'elapsed_time:-'
- title_variant = 'Time'
- object_search_display = 'time data'
- elif 'diskio' == variant:
- default_orderby = 'disk_io:-'
- title_variant = 'Disk I/O'
- object_search_display = 'disk I/O data'
- elif 'cputime' == variant:
- default_orderby = 'cpu_time_system:-'
- title_variant='CPU time'
- object_search_display = 'CPU time data'
- else:
- default_orderby = 'order:+'
- title_variant = 'Tasks'
- object_search_display = 'tasks'
-
- (pagesize, orderby) = _get_parameters_values(request, 25, default_orderby)
-
- mandatory_parameters = {'count': pagesize, 'page' : 1, 'orderby': orderby}
-
- template = 'tasks.html'
- retval = _verify_parameters( request.GET, mandatory_parameters )
- if retval:
- if task_anchor:
- mandatory_parameters['anchor']=task_anchor
- return _redirect_parameters( variant, request.GET, mandatory_parameters, build_id = build_id)
- (filter_string, search_term, ordering_string) = _search_tuple(request, Task)
- queryset_all = Task.objects.filter(build=build_id).exclude(order__isnull=True).exclude(outcome=Task.OUTCOME_NA)
- queryset_all = queryset_all.select_related("recipe", "build")
-
- queryset_with_search = _get_queryset(Task, queryset_all, None , search_term, ordering_string, 'order')
-
- if ordering_string.startswith('outcome'):
- queryset = _get_queryset(Task, queryset_all, filter_string, search_term, 'order:+', 'order')
- queryset = sorted(queryset, key=lambda ur: (ur.outcome_text), reverse=ordering_string.endswith('-'))
- elif ordering_string.startswith('sstate_result'):
- queryset = _get_queryset(Task, queryset_all, filter_string, search_term, 'order:+', 'order')
- queryset = sorted(queryset, key=lambda ur: (ur.sstate_text), reverse=ordering_string.endswith('-'))
- else:
- queryset = _get_queryset(Task, queryset_all, filter_string, search_term, ordering_string, 'order')
-
-
- # compute the anchor's page
- if anchor:
- request.GET = request.GET.copy()
- del request.GET['anchor']
- i=0
- a=int(anchor)
- count_per_page=int(pagesize)
- for task_object in queryset.iterator():
- if a == task_object.order:
- new_page= (i / count_per_page ) + 1
- request.GET.__setitem__('page', new_page)
- mandatory_parameters['page']=new_page
- return _redirect_parameters( variant, request.GET, mandatory_parameters, build_id = build_id)
- i += 1
-
- task_objects = _build_page_range(Paginator(queryset, pagesize),request.GET.get('page', 1))
-
- # define (and modify by variants) the 'tablecols' members
- tc_order={
- 'name':'Order',
- 'qhelp':'The running sequence of each task in the build',
- 'clclass': 'order', 'hidden' : 1,
- 'orderkey' : 'order',
- 'orderfield':_get_toggle_order(request, "order"),
- 'ordericon':_get_toggle_order_icon(request, "order")}
- if 'tasks' == variant:
- tc_order['hidden']='0'
- del tc_order['clclass']
-
- tc_recipe={
- 'name':'Recipe',
- 'qhelp':'The name of the recipe to which each task applies',
- 'orderkey' : 'recipe__name',
- 'orderfield': _get_toggle_order(request, "recipe__name"),
- 'ordericon':_get_toggle_order_icon(request, "recipe__name"),
- }
- tc_recipe_version={
- 'name':'Recipe version',
- 'qhelp':'The version of the recipe to which each task applies',
- 'clclass': 'recipe_version', 'hidden' : 1,
- }
- tc_task={
- 'name':'Task',
- 'qhelp':'The name of the task',
- 'orderfield': _get_toggle_order(request, "task_name"),
- 'ordericon':_get_toggle_order_icon(request, "task_name"),
- 'orderkey' : 'task_name',
- }
- tc_executed={
- 'name':'Executed',
- 'qhelp':"This value tells you if a task had to run (executed) in order to generate the task output, or if the output was provided by another task and therefore the task didn't need to run (not executed)",
- 'clclass': 'executed', 'hidden' : 0,
- 'orderfield': _get_toggle_order(request, "task_executed"),
- 'ordericon':_get_toggle_order_icon(request, "task_executed"),
- 'orderkey' : 'task_executed',
- 'filter' : {
- 'class' : 'executed',
- 'label': 'Show:',
- 'options' : [
- ('Executed Tasks', 'task_executed:1', queryset_with_search.filter(task_executed=1).count()),
- ('Not Executed Tasks', 'task_executed:0', queryset_with_search.filter(task_executed=0).count()),
- ]
- }
-
- }
- tc_outcome={
- 'name':'Outcome',
- 'qhelp':"This column tells you if 'executed' tasks succeeded or failed. The column also tells you why 'not executed' tasks did not need to run",
- 'clclass': 'outcome', 'hidden' : 0,
- 'orderfield': _get_toggle_order(request, "outcome"),
- 'ordericon':_get_toggle_order_icon(request, "outcome"),
- 'orderkey' : 'outcome',
- 'filter' : {
- 'class' : 'outcome',
- 'label': 'Show:',
- 'options' : [
- ('Succeeded Tasks', 'outcome:%d'%Task.OUTCOME_SUCCESS, queryset_with_search.filter(outcome=Task.OUTCOME_SUCCESS).count(), "'Succeeded' tasks are those that ran and completed during the build" ),
- ('Failed Tasks', 'outcome:%d'%Task.OUTCOME_FAILED, queryset_with_search.filter(outcome=Task.OUTCOME_FAILED).count(), "'Failed' tasks are those that ran but did not complete during the build"),
- ('Cached Tasks', 'outcome:%d'%Task.OUTCOME_CACHED, queryset_with_search.filter(outcome=Task.OUTCOME_CACHED).count(), 'Cached tasks restore output from the <code>sstate-cache</code> directory or mirrors'),
- ('Prebuilt Tasks', 'outcome:%d'%Task.OUTCOME_PREBUILT, queryset_with_search.filter(outcome=Task.OUTCOME_PREBUILT).count(),'Prebuilt tasks didn\'t need to run because their output was reused from a previous build'),
- ('Covered Tasks', 'outcome:%d'%Task.OUTCOME_COVERED, queryset_with_search.filter(outcome=Task.OUTCOME_COVERED).count(), 'Covered tasks didn\'t need to run because their output is provided by another task in this build'),
- ('Empty Tasks', 'outcome:%d'%Task.OUTCOME_EMPTY, queryset_with_search.filter(outcome=Task.OUTCOME_EMPTY).count(), 'Empty tasks have no executable content'),
- ]
- }
-
- }
-
- tc_cache={
- 'name':'Cache attempt',
- 'qhelp':'This column tells you if a task tried to restore output from the <code>sstate-cache</code> directory or mirrors, and reports the result: Succeeded, Failed or File not in cache',
- 'clclass': 'cache_attempt', 'hidden' : 0,
- 'orderfield': _get_toggle_order(request, "sstate_result"),
- 'ordericon':_get_toggle_order_icon(request, "sstate_result"),
- 'orderkey' : 'sstate_result',
- 'filter' : {
- 'class' : 'cache_attempt',
- 'label': 'Show:',
- 'options' : [
- ('Tasks with cache attempts', 'sstate_result__gt:%d'%Task.SSTATE_NA, queryset_with_search.filter(sstate_result__gt=Task.SSTATE_NA).count(), 'Show all tasks that tried to restore ouput from the <code>sstate-cache</code> directory or mirrors'),
- ("Tasks with 'File not in cache' attempts", 'sstate_result:%d'%Task.SSTATE_MISS, queryset_with_search.filter(sstate_result=Task.SSTATE_MISS).count(), 'Show tasks that tried to restore output, but did not find it in the <code>sstate-cache</code> directory or mirrors'),
- ("Tasks with 'Failed' cache attempts", 'sstate_result:%d'%Task.SSTATE_FAILED, queryset_with_search.filter(sstate_result=Task.SSTATE_FAILED).count(), 'Show tasks that found the required output in the <code>sstate-cache</code> directory or mirrors, but could not restore it'),
- ("Tasks with 'Succeeded' cache attempts", 'sstate_result:%d'%Task.SSTATE_RESTORED, queryset_with_search.filter(sstate_result=Task.SSTATE_RESTORED).count(), 'Show tasks that successfully restored the required output from the <code>sstate-cache</code> directory or mirrors'),
- ]
- }
-
- }
- #if 'tasks' == variant: tc_cache['hidden']='0';
- tc_time={
- 'name':'Time (secs)',
- 'qhelp':'How long it took the task to finish in seconds',
- 'orderfield': _get_toggle_order(request, "elapsed_time", True),
- 'ordericon':_get_toggle_order_icon(request, "elapsed_time"),
- 'orderkey' : 'elapsed_time',
- 'clclass': 'time_taken', 'hidden' : 1,
- }
- if 'buildtime' == variant:
- tc_time['hidden']='0'
- del tc_time['clclass']
- tc_cache['hidden']='1'
-
- tc_cpu_time_system={
- 'name':'System CPU time (secs)',
- 'qhelp':'Total amount of time spent executing in kernel mode, in ' +
- 'seconds. Note that this time can be greater than the task ' +
- 'time due to parallel execution.',
- 'orderfield': _get_toggle_order(request, "cpu_time_system", True),
- 'ordericon':_get_toggle_order_icon(request, "cpu_time_system"),
- 'orderkey' : 'cpu_time_system',
- 'clclass': 'cpu_time_system', 'hidden' : 1,
- }
-
- tc_cpu_time_user={
- 'name':'User CPU time (secs)',
- 'qhelp':'Total amount of time spent executing in user mode, in seconds. ' +
- 'Note that this time can be greater than the task time due to ' +
- 'parallel execution.',
- 'orderfield': _get_toggle_order(request, "cpu_time_user", True),
- 'ordericon':_get_toggle_order_icon(request, "cpu_time_user"),
- 'orderkey' : 'cpu_time_user',
- 'clclass': 'cpu_time_user', 'hidden' : 1,
- }
-
- if 'cputime' == variant:
- tc_cpu_time_system['hidden']='0'
- tc_cpu_time_user['hidden']='0'
- del tc_cpu_time_system['clclass']
- del tc_cpu_time_user['clclass']
- tc_cache['hidden']='1'
-
- tc_diskio={
- 'name':'Disk I/O (bytes)',
- 'qhelp':'Number of bytes written to and read from the disk during the task',
- 'orderfield': _get_toggle_order(request, "disk_io", True),
- 'ordericon':_get_toggle_order_icon(request, "disk_io"),
- 'orderkey' : 'disk_io',
- 'clclass': 'disk_io', 'hidden' : 1,
- }
- if 'diskio' == variant:
- tc_diskio['hidden']='0'
- del tc_diskio['clclass']
- tc_cache['hidden']='1'
-
- build = Build.objects.get(pk=build_id)
-
- context = { 'objectname': variant,
- 'object_search_display': object_search_display,
- 'filter_search_display': filter_search_display,
- 'mainheading': title_variant,
- 'build': build,
- 'project': build.project,
- 'objects': task_objects,
- 'default_orderby' : default_orderby,
- 'search_term': search_term,
- 'total_count': queryset_with_search.count(),
- 'tablecols':[
- tc_order,
- tc_recipe,
- tc_recipe_version,
- tc_task,
- tc_executed,
- tc_outcome,
- tc_cache,
- tc_time,
- tc_cpu_time_system,
- tc_cpu_time_user,
- tc_diskio,
- ]}
-
-
- response = render(request, template, context)
- _set_parameters_values(pagesize, orderby, request)
- return response
-
-def tasks(request, build_id):
- return tasks_common(request, build_id, 'tasks', '')
-
-def tasks_task(request, build_id, task_id):
- return tasks_common(request, build_id, 'tasks', task_id)
-
-def buildtime(request, build_id):
- return tasks_common(request, build_id, 'buildtime', '')
-
-def diskio(request, build_id):
- return tasks_common(request, build_id, 'diskio', '')
-
-def cputime(request, build_id):
- return tasks_common(request, build_id, 'cputime', '')
-
-def recipes(request, build_id):
- template = 'recipes.html'
- (pagesize, orderby) = _get_parameters_values(request, 100, 'name:+')
- mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby }
- retval = _verify_parameters( request.GET, mandatory_parameters )
- if retval:
- return _redirect_parameters( 'recipes', request.GET, mandatory_parameters, build_id = build_id)
- (filter_string, search_term, ordering_string) = _search_tuple(request, Recipe)
-
- build = Build.objects.get(pk=build_id)
-
- queryset = build.get_recipes()
- queryset = _get_queryset(Recipe, queryset, filter_string, search_term, ordering_string, 'name')
-
- recipes = _build_page_range(Paginator(queryset, pagesize),request.GET.get('page', 1))
-
- # prefetch the forward and reverse recipe dependencies
- deps = { }
- revs = { }
- queryset_dependency=Recipe_Dependency.objects.filter(recipe__layer_version__build_id = build_id).select_related("depends_on", "recipe")
- for recipe in recipes:
- deplist = [ ]
- for recipe_dep in [x for x in queryset_dependency if x.recipe_id == recipe.id]:
- deplist.append(recipe_dep)
- deps[recipe.id] = deplist
- revlist = [ ]
- for recipe_dep in [x for x in queryset_dependency if x.depends_on_id == recipe.id]:
- revlist.append(recipe_dep)
- revs[recipe.id] = revlist
-
- context = {
- 'objectname': 'recipes',
- 'build': build,
- 'project': build.project,
- 'objects': recipes,
- 'default_orderby' : 'name:+',
- 'recipe_deps' : deps,
- 'recipe_revs' : revs,
- 'tablecols':[
- {
- 'name':'Recipe',
- 'qhelp':'Information about a single piece of software, including where to download the source, configuration options, how to compile the source files and how to package the compiled output',
- 'orderfield': _get_toggle_order(request, "name"),
- 'ordericon':_get_toggle_order_icon(request, "name"),
- },
- {
- 'name':'Recipe version',
- 'qhelp':'The recipe version and revision',
- },
- {
- 'name':'Dependencies',
- 'qhelp':'Recipe build-time dependencies (i.e. other recipes)',
- 'clclass': 'depends_on', 'hidden': 1,
- },
- {
- 'name':'Reverse dependencies',
- 'qhelp':'Recipe build-time reverse dependencies (i.e. the recipes that depend on this recipe)',
- 'clclass': 'depends_by', 'hidden': 1,
- },
- {
- 'name':'Recipe file',
- 'qhelp':'Path to the recipe .bb file',
- 'orderfield': _get_toggle_order(request, "file_path"),
- 'ordericon':_get_toggle_order_icon(request, "file_path"),
- 'orderkey' : 'file_path',
- 'clclass': 'recipe_file', 'hidden': 0,
- },
- {
- 'name':'Section',
- 'qhelp':'The section in which recipes should be categorized',
- 'orderfield': _get_toggle_order(request, "section"),
- 'ordericon':_get_toggle_order_icon(request, "section"),
- 'orderkey' : 'section',
- 'clclass': 'recipe_section', 'hidden': 0,
- },
- {
- 'name':'License',
- 'qhelp':'The list of source licenses for the recipe. Multiple license names separated by the pipe character indicates a choice between licenses. Multiple license names separated by the ampersand character indicates multiple licenses exist that cover different parts of the source',
- 'orderfield': _get_toggle_order(request, "license"),
- 'ordericon':_get_toggle_order_icon(request, "license"),
- 'orderkey' : 'license',
- 'clclass': 'recipe_license', 'hidden': 0,
- },
- {
- 'name':'Layer',
- 'qhelp':'The name of the layer providing the recipe',
- 'orderfield': _get_toggle_order(request, "layer_version__layer__name"),
- 'ordericon':_get_toggle_order_icon(request, "layer_version__layer__name"),
- 'orderkey' : 'layer_version__layer__name',
- 'clclass': 'layer_version__layer__name', 'hidden': 0,
- },
- {
- 'name':'Layer branch',
- 'qhelp':'The Git branch of the layer providing the recipe',
- 'orderfield': _get_toggle_order(request, "layer_version__branch"),
- 'ordericon':_get_toggle_order_icon(request, "layer_version__branch"),
- 'orderkey' : 'layer_version__branch',
- 'clclass': 'layer_version__branch', 'hidden': 1,
- },
- {
- 'name':'Layer commit',
- 'qhelp':'The Git commit of the layer providing the recipe',
- 'clclass': 'layer_version__layer__commit', 'hidden': 1,
- },
- ]
- }
-
- response = render(request, template, context)
- _set_parameters_values(pagesize, orderby, request)
- return response
-
def configuration(request, build_id):
template = 'configuration.html'
@@ -1437,7 +915,6 @@ def configvars(request, build_id):
},
{'name': 'Value',
'qhelp': "The value assigned to the variable",
- 'dclass': "span4",
},
{'name': 'Set in file',
'qhelp': "The last configuration file that touched the variable value",
@@ -1474,96 +951,6 @@ def configvars(request, build_id):
_set_parameters_values(pagesize, orderby, request)
return response
-def bpackage(request, build_id):
- template = 'bpackage.html'
- (pagesize, orderby) = _get_parameters_values(request, 100, 'name:+')
- mandatory_parameters = { 'count' : pagesize, 'page' : 1, 'orderby' : orderby }
- retval = _verify_parameters( request.GET, mandatory_parameters )
- if retval:
- return _redirect_parameters( 'packages', request.GET, mandatory_parameters, build_id = build_id)
- (filter_string, search_term, ordering_string) = _search_tuple(request, Package)
- queryset = Package.objects.filter(build = build_id).filter(size__gte=0)
- queryset = _get_queryset(Package, queryset, filter_string, search_term, ordering_string, 'name')
-
- packages = _build_page_range(Paginator(queryset, pagesize),request.GET.get('page', 1))
-
- build = Build.objects.get( pk = build_id )
-
- context = {
- 'objectname': 'packages built',
- 'build': build,
- 'project': build.project,
- 'objects' : packages,
- 'default_orderby' : 'name:+',
- 'tablecols':[
- {
- 'name':'Package',
- 'qhelp':'Packaged output resulting from building a recipe',
- 'orderfield': _get_toggle_order(request, "name"),
- 'ordericon':_get_toggle_order_icon(request, "name"),
- },
- {
- 'name':'Package version',
- 'qhelp':'The package version and revision',
- },
- {
- 'name':'Size',
- 'qhelp':'The size of the package',
- 'orderfield': _get_toggle_order(request, "size", True),
- 'ordericon':_get_toggle_order_icon(request, "size"),
- 'orderkey' : 'size',
- 'clclass': 'size', 'hidden': 0,
- 'dclass' : 'span2',
- },
- {
- 'name':'License',
- 'qhelp':'The license under which the package is distributed. Multiple license names separated by the pipe character indicates a choice between licenses. Multiple license names separated by the ampersand character indicates multiple licenses exist that cover different parts of the source',
- 'orderfield': _get_toggle_order(request, "license"),
- 'ordericon':_get_toggle_order_icon(request, "license"),
- 'orderkey' : 'license',
- 'clclass': 'license', 'hidden': 1,
- },
- {
- 'name':'Recipe',
- 'qhelp':'The name of the recipe building the package',
- 'orderfield': _get_toggle_order(request, "recipe__name"),
- 'ordericon':_get_toggle_order_icon(request, "recipe__name"),
- 'orderkey' : 'recipe__name',
- 'clclass': 'recipe__name', 'hidden': 0,
- },
- {
- 'name':'Recipe version',
- 'qhelp':'Version and revision of the recipe building the package',
- 'clclass': 'recipe__version', 'hidden': 1,
- },
- {
- 'name':'Layer',
- 'qhelp':'The name of the layer providing the recipe that builds the package',
- 'orderfield': _get_toggle_order(request, "recipe__layer_version__layer__name"),
- 'ordericon':_get_toggle_order_icon(request, "recipe__layer_version__layer__name"),
- 'orderkey' : 'recipe__layer_version__layer__name',
- 'clclass': 'recipe__layer_version__layer__name', 'hidden': 1,
- },
- {
- 'name':'Layer branch',
- 'qhelp':'The Git branch of the layer providing the recipe that builds the package',
- 'orderfield': _get_toggle_order(request, "recipe__layer_version__branch"),
- 'ordericon':_get_toggle_order_icon(request, "recipe__layer_version__branch"),
- 'orderkey' : 'recipe__layer_version__branch',
- 'clclass': 'recipe__layer_version__branch', 'hidden': 1,
- },
- {
- 'name':'Layer commit',
- 'qhelp':'The Git commit of the layer providing the recipe that builds the package',
- 'clclass': 'recipe__layer_version__layer__commit', 'hidden': 1,
- },
- ]
- }
-
- response = render(request, template, context)
- _set_parameters_values(pagesize, orderby, request)
- return response
-
def bfile(request, build_id, package_id):
template = 'bfile.html'
files = Package_File.objects.filter(package = package_id)
@@ -1905,7 +1292,7 @@ if True:
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
- from orm.models import Branch, LayerSource, ToasterSetting, Release, Machine, LayerVersionDependency
+ from orm.models import LayerSource, ToasterSetting, Release, Machine, LayerVersionDependency
from bldcontrol.models import BuildRequest
import traceback
@@ -1938,10 +1325,10 @@ if True:
if ptype == "build":
mandatory_fields.append('projectversion')
# make sure we have values for all mandatory_fields
- if reduce( lambda x, y: x or y, map(lambda x: len(request.POST.get(x, '')) == 0, mandatory_fields)):
- # set alert for missing fields
- raise BadParameterException("Fields missing: " +
- ", ".join([x for x in mandatory_fields if len(request.POST.get(x, '')) == 0 ]))
+ missing = [field for field in mandatory_fields if len(request.POST.get(field, '')) == 0]
+ if missing:
+ # set alert for missing fields
+ raise BadParameterException("Fields missing: %s" % ", ".join(missing))
if not request.user.is_authenticated():
user = authenticate(username = request.POST.get('username', '_anonuser'), password = 'nopass')
@@ -1964,7 +1351,8 @@ if True:
except (IntegrityError, BadParameterException) as e:
# fill in page with previously submitted values
- map(lambda x: context.__setitem__(x, request.POST.get(x, "-- missing")), mandatory_fields)
+ for field in mandatory_fields:
+ context.__setitem__(field, request.POST.get(field, "-- missing"))
if isinstance(e, IntegrityError) and "username" in str(e):
context['alert'] = "Your chosen username is already used"
else:
@@ -1973,128 +1361,11 @@ if True:
raise Exception("Invalid HTTP method for this page")
-
-
# Shows the edit project page
- @_template_renderer('project.html')
def project(request, pid):
- prj = Project.objects.get(id = pid)
-
- try:
- puser = User.objects.get(id = prj.user_id)
- except User.DoesNotExist:
- puser = None
-
- # execute POST requests
- if request.method == "POST":
- # add layers
- if 'layerAdd' in request.POST and len(request.POST['layerAdd']) > 0:
- for lc in Layer_Version.objects.filter(pk__in=[i for i in request.POST['layerAdd'].split(",") if len(i) > 0]):
- ProjectLayer.objects.get_or_create(project = prj, layercommit = lc)
-
- # remove layers
- if 'layerDel' in request.POST and len(request.POST['layerDel']) > 0:
- for t in request.POST['layerDel'].strip().split(" "):
- pt = ProjectLayer.objects.filter(project = prj, layercommit_id = int(t)).delete()
-
- if 'projectName' in request.POST:
- prj.name = request.POST['projectName']
- prj.save();
-
- if 'projectVersion' in request.POST:
- # If the release is the current project then return now
- if prj.release.pk == int(request.POST.get('projectVersion',-1)):
- return {}
-
- prj.release = Release.objects.get(pk = request.POST['projectVersion'])
- # we need to change the bitbake version
- prj.bitbake_version = prj.release.bitbake_version
- prj.save()
- # we need to change the layers
- for project in prj.projectlayer_set.all():
- # find and add a similarly-named layer on the new branch
- try:
- layer_versions = prj.get_all_compatible_layer_versions()
- layer_versions = layer_versions.filter(layer__name = project.layercommit.layer.name)
- ProjectLayer.objects.get_or_create(project = prj, layercommit = layer_versions.first())
- except IndexError:
- pass
- finally:
- # get rid of the old entry
- project.delete()
-
- if 'machineName' in request.POST:
- machinevar = prj.projectvariable_set.get(name="MACHINE")
- machinevar.value=request.POST['machineName']
- machinevar.save()
-
-
- # we use implicit knowledge of the current user's project to filter layer information, e.g.
- pid = prj.id
-
- from collections import Counter
- freqtargets = []
- try:
- freqtargets += map(lambda x: x.target, reduce(lambda x, y: x + y, map(lambda x: list(x.target_set.all()), Build.objects.filter(project = prj, outcome__lt = Build.IN_PROGRESS))))
- freqtargets += map(lambda x: x.target, reduce(lambda x, y: x + y, map(lambda x: list(x.brtarget_set.all()), BuildRequest.objects.filter(project = prj, state = BuildRequest.REQ_FAILED))))
- except TypeError:
- pass
- freqtargets = Counter(freqtargets)
- freqtargets = sorted(freqtargets, key = lambda x: freqtargets[x], reverse=True)
-
- context = {
- "project" : prj,
- "lvs_nos" : Layer_Version.objects.all().count(),
- "completedbuilds": Build.objects.exclude(outcome = Build.IN_PROGRESS).filter(project_id = pid),
- "prj" : {"name": prj.name, },
- "buildrequests" : prj.build_set.filter(outcome=Build.IN_PROGRESS),
- "builds" : Build.get_recent(prj),
- "layers" : map(lambda x: {
- "id": x.layercommit.pk,
- "orderid": x.pk,
- "name" : x.layercommit.layer.name,
- "vcs_url": x.layercommit.layer.vcs_url,
- "vcs_reference" : x.layercommit.get_vcs_reference(),
- "url": x.layercommit.layer.layer_index_url,
- "layerdetailurl": x.layercommit.get_detailspage_url(prj.pk),
- # This branch name is actually the release
- "branch" : { "name" : x.layercommit.get_vcs_reference(), "layersource" : x.layercommit.up_branch.layer_source.name if x.layercommit.up_branch != None else None}},
- prj.projectlayer_set.all().order_by("id")),
- "targets" : map(lambda x: {"target" : x.target, "task" : x.task, "pk": x.pk}, prj.projecttarget_set.all()),
- "variables": map(lambda x: (x.name, x.value), prj.projectvariable_set.all()),
- "freqtargets": freqtargets[:5],
- "releases": map(lambda x: {"id": x.pk, "name": x.name, "description":x.description}, Release.objects.all()),
- "project_html": 1,
- "recipesTypeAheadUrl": reverse('xhr_recipestypeahead', args=(prj.pk,)),
- "projectBuildsUrl": reverse('projectbuilds', args=(prj.pk,)),
- }
-
- if prj.release is not None:
- context['release'] = { "id": prj.release.pk, "name": prj.release.name, "description": prj.release.description}
-
-
- try:
- context["machine"] = {"name": prj.projectvariable_set.get(name="MACHINE").value}
- except ProjectVariable.DoesNotExist:
- context["machine"] = None
- try:
- context["distro"] = prj.projectvariable_set.get(name="DISTRO").value
- except ProjectVariable.DoesNotExist:
- context["distro"] = "-- not set yet"
-
- return context
-
- def xhr_response(fun):
- """
- Decorator for REST methods.
- calls jsonfilter on the returned dictionary and returns result
- as HttpResponse object of content_type application/json
- """
- @wraps(fun)
- def wrapper(*args, **kwds):
- return HttpResponse(jsonfilter(fun(*args, **kwds)),
- content_type="application/json")
- return wrapper
+ project = Project.objects.get(pk=pid)
+ context = {"project": project}
+ return render(request, "project.html", context)
def jsunittests(request):
""" Provides a page for the js unit tests """
@@ -2154,8 +1425,7 @@ if True:
retval.append(project)
return response({"error":"ok",
- "rows" : map( _lv_to_dict(prj),
- map(lambda x: x.layercommit, retval ))
+ "rows": [_lv_to_dict(prj) for y in [x.layercommit for x in retval]]
})
except Exception as e:
@@ -2164,11 +1434,16 @@ if True:
def xhr_configvaredit(request, pid):
try:
prj = Project.objects.get(id = pid)
+ # There are cases where user can add variables which hold values
+ # like http://, file:/// etc. In such case a simple split(":")
+ # would fail. One example is SSTATE_MIRRORS variable. So we use
+ # max_split var to handle them.
+ max_split = 1
# add conf variables
if 'configvarAdd' in request.POST:
t=request.POST['configvarAdd'].strip()
if ":" in t:
- variable, value = t.split(":")
+ variable, value = t.split(":", max_split)
else:
variable = t
value = ""
@@ -2178,7 +1453,7 @@ if True:
if 'configvarChange' in request.POST:
t=request.POST['configvarChange'].strip()
if ":" in t:
- variable, value = t.split(":")
+ variable, value = t.split(":", max_split)
else:
variable = t
value = ""
@@ -2201,7 +1476,7 @@ if True:
return_data = {
"error": "ok",
- 'configvars' : map(lambda x: (x.name, x.value, x.pk), configvars_query),
+ 'configvars': [(x.name, x.value, x.pk) for x in configvars_query]
}
try:
return_data['distro'] = ProjectVariable.objects.get(project = prj, name = "DISTRO").value,
@@ -2235,10 +1510,10 @@ if True:
def xhr_importlayer(request):
- if (not request.POST.has_key('vcs_url') or
- not request.POST.has_key('name') or
- not request.POST.has_key('git_ref') or
- not request.POST.has_key('project_id')):
+ if ('vcs_url' not in request.POST or
+ 'name' not in request.POST or
+ 'git_ref' not in request.POST or
+ 'project_id' not in request.POST):
return HttpResponse(jsonfilter({"error": "Missing parameters; requires vcs_url, name, git_ref and project_id"}), content_type = "application/json")
layers_added = [];
@@ -2253,18 +1528,12 @@ if True:
prj = Project.objects.get(pk=request.POST['project_id'])
# Strip trailing/leading whitespace from all values
- # put into a new dict because POST one is immutable
+ # put into a new dict because POST one is immutable.
post_data = dict()
- for key,val in request.POST.iteritems():
+ for key,val in request.POST.items():
post_data[key] = val.strip()
- # We need to know what release the current project is so that we
- # can set the imported layer's up_branch_id
- prj_branch_name = Release.objects.get(pk=prj.release_id).branch_name
- up_branch, branch_created = Branch.objects.get_or_create(name=prj_branch_name, layer_source_id=LayerSource.TYPE_IMPORTED)
-
- layer_source = LayerSource.objects.get(sourcetype=LayerSource.TYPE_IMPORTED)
try:
layer, layer_created = Layer.objects.get_or_create(name=post_data['name'])
except MultipleObjectsReturned:
@@ -2272,8 +1541,8 @@ if True:
if layer:
if layer_created:
- layer.layer_source = layer_source
- layer.vcs_url = post_data['vcs_url']
+ layer.vcs_url = post_data.get('vcs_url')
+ layer.local_source_dir = post_data.get('local_source_dir')
layer.up_date = timezone.now()
layer.save()
else:
@@ -2283,18 +1552,30 @@ if True:
if layer.vcs_url != post_data['vcs_url']:
return HttpResponse(jsonfilter({"error": "hint-layer-exists-with-different-url" , "current_url" : layer.vcs_url, "current_id": layer.id }), content_type = "application/json")
-
- layer_version, version_created = Layer_Version.objects.get_or_create(layer_source=layer_source, layer=layer, project=prj, up_branch_id=up_branch.id,branch=post_data['git_ref'], commit=post_data['git_ref'], dirpath=post_data['dir_path'])
+ layer_version, version_created = \
+ Layer_Version.objects.get_or_create(
+ layer_source=LayerSource.TYPE_IMPORTED,
+ layer=layer, project=prj,
+ release=prj.release,
+ branch=post_data['git_ref'],
+ commit=post_data['git_ref'],
+ dirpath=post_data['dir_path'])
if layer_version:
if not version_created:
- return HttpResponse(jsonfilter({"error": "hint-layer-version-exists", "existing_layer_version": layer_version.id }), content_type = "application/json")
+ return HttpResponse(jsonfilter({"error":
+ "hint-layer-version-exists",
+ "existing_layer_version":
+ layer_version.id }),
+ content_type = "application/json")
+
+ layer_version.layer_source = LayerSource.TYPE_IMPORTED
layer_version.up_date = timezone.now()
layer_version.save()
# Add the dependencies specified for this new layer
- if (post_data.has_key("layer_deps") and
+ if ('layer_deps' in post_data and
version_created and
len(post_data["layer_deps"]) > 0):
for layer_dep_id in post_data["layer_deps"].split(","):
@@ -2343,231 +1624,6 @@ if True:
return HttpResponse(jsonfilter(json_response), content_type = "application/json")
- def xhr_updatelayer(request):
-
- def error_response(error):
- return HttpResponse(jsonfilter({"error": error}), content_type = "application/json")
-
- if not request.POST.has_key("layer_version_id"):
- return error_response("Please specify a layer version id")
- try:
- layer_version_id = request.POST["layer_version_id"]
- layer_version = Layer_Version.objects.get(id=layer_version_id)
- except Layer_Version.DoesNotExist:
- return error_response("Cannot find layer to update")
-
-
- if request.POST.has_key("vcs_url"):
- layer_version.layer.vcs_url = request.POST["vcs_url"]
- if request.POST.has_key("dirpath"):
- layer_version.dirpath = request.POST["dirpath"]
- if request.POST.has_key("commit"):
- layer_version.commit = request.POST["commit"]
- if request.POST.has_key("up_branch"):
- layer_version.up_branch_id = int(request.POST["up_branch"])
-
- if request.POST.has_key("add_dep"):
- lvd = LayerVersionDependency(layer_version=layer_version, depends_on_id=request.POST["add_dep"])
- lvd.save()
-
- if request.POST.has_key("rm_dep"):
- rm_dep = LayerVersionDependency.objects.get(layer_version=layer_version, depends_on_id=request.POST["rm_dep"])
- rm_dep.delete()
-
- if request.POST.has_key("summary"):
- layer_version.layer.summary = request.POST["summary"]
- if request.POST.has_key("description"):
- layer_version.layer.description = request.POST["description"]
-
- try:
- layer_version.layer.save()
- layer_version.save()
- except Exception as e:
- return error_response("Could not update layer version entry: %s" % e)
-
- return HttpResponse(jsonfilter({"error": "ok",}), content_type = "application/json")
-
- @xhr_response
- def xhr_customrecipe(request):
- """
- Custom image recipe REST API
-
- Entry point: /xhr_customrecipe/
- Method: POST
-
- Args:
- name: name of custom recipe to create
- project: target project id of orm.models.Project
- base: base recipe id of orm.models.Recipe
-
- Returns:
- {"error": "ok",
- "url": <url of the created recipe>}
- or
- {"error": <error message>}
- """
- # check if request has all required parameters
- for param in ('name', 'project', 'base'):
- if param not in request.POST:
- return {"error": "Missing parameter '%s'" % param}
-
- # get project and baserecipe objects
- params = {}
- for name, model in [("project", Project),
- ("base", Recipe)]:
- value = request.POST[name]
- try:
- params[name] = model.objects.get(id=value)
- except model.DoesNotExist:
- return {"error": "Invalid %s id %s" % (name, value)}
-
- # create custom recipe
- try:
-
- # Only allowed chars in name are a-z, 0-9 and -
- if re.search(r'[^a-z|0-9|-]', request.POST["name"]):
- return {"error": "invalid-name"}
-
- custom_images = CustomImageRecipe.objects.all()
-
- # Are there any recipes with this name already in our project?
- existing_image_recipes_in_project = custom_images.filter(
- name=request.POST["name"], project=params["project"])
-
- if existing_image_recipes_in_project.count() > 0:
- return {"error": "image-already-exists"}
-
- # Are there any recipes with this name which aren't custom
- # image recipes?
- custom_image_ids = custom_images.values_list('id', flat=True)
- existing_non_image_recipes = Recipe.objects.filter(
- Q(name=request.POST["name"]) & ~Q(pk__in=custom_image_ids)
- )
-
- if existing_non_image_recipes.count() > 0:
- return {"error": "recipe-already-exists"}
-
- # create layer 'Custom layer' and verion if needed
- layer = Layer.objects.get_or_create(
- name=CustomImageRecipe.LAYER_NAME,
- summary="Layer for custom recipes",
- vcs_url="file:///toaster_created_layer")[0]
-
- # Check if we have a layer version already
- # We don't use get_or_create here because the dirpath will change
- # and is a required field
- lver = Layer_Version.objects.filter(Q(project=params['project']) &
- Q(layer=layer) &
- Q(build=None)).last()
- if lver == None:
- lver, created = Layer_Version.objects.get_or_create(
- project=params['project'],
- layer=layer,
- dirpath="toaster_created_layer")
-
- # Add a dependency on our layer to the base recipe's layer
- LayerVersionDependency.objects.get_or_create(
- layer_version=lver,
- depends_on=params["base"].layer_version)
-
- # Add it to our current project if needed
- ProjectLayer.objects.get_or_create(project=params['project'],
- layercommit=lver,
- optional=False)
-
- # Create the actual recipe
- recipe, created = CustomImageRecipe.objects.get_or_create(
- name=request.POST["name"],
- base_recipe=params["base"],
- project=params["project"],
- layer_version=lver,
- is_image=True)
-
- # If we created the object then setup these fields. They may get
- # overwritten later on and cause the get_or_create to create a
- # duplicate if they've changed.
- if created:
- recipe.file_path = request.POST["name"]
- recipe.license = "MIT"
- recipe.version = "0.1"
- recipe.save()
-
- except Error as err:
- return {"error": "Can't create custom recipe: %s" % err}
-
- # Find the package list from the last build of this recipe/target
- target = Target.objects.filter(Q(build__outcome=Build.SUCCEEDED) &
- Q(build__project=params['project']) &
- (Q(target=params['base'].name) |
- Q(target=recipe.name))).last()
- if target:
- # Copy in every package
- # We don't want these packages to be linked to anything because
- # that underlying data may change e.g. delete a build
- for tpackage in target.target_installed_package_set.all():
- try:
- built_package = tpackage.package
- # The package had no recipe information so is a ghost
- # package skip it
- if built_package.recipe == None:
- continue;
-
- config_package = CustomImagePackage.objects.get(
- name=built_package.name)
-
- recipe.includes_set.add(config_package)
- except Exception as e:
- logger.warning("Error adding package %s %s" %
- (tpackage.package.name, e))
- pass
-
- return {"error": "ok",
- "packages" : recipe.get_all_packages().count(),
- "url": reverse('customrecipe', args=(params['project'].pk,
- recipe.id))}
-
- @xhr_response
- def xhr_customrecipe_id(request, recipe_id):
- """
- Set of ReST API processors working with recipe id.
-
- Entry point: /xhr_customrecipe/<recipe_id>
-
- Methods:
- GET - Get details of custom image recipe
- DELETE - Delete custom image recipe
-
- Returns:
- GET:
- {"error": "ok",
- "info": dictionary of field name -> value pairs
- of the CustomImageRecipe model}
- DELETE:
- {"error": "ok"}
- or
- {"error": <error message>}
- """
- try:
- custom_recipe = CustomImageRecipe.objects.get(id=recipe_id)
- except CustomImageRecipe.DoesNotExist:
- return {"error": "Custom recipe with id=%s "
- "not found" % recipe_id}
-
- if request.method == 'GET':
- info = {"id" : custom_recipe.id,
- "name" : custom_recipe.name,
- "base_recipe_id": custom_recipe.base_recipe.id,
- "project_id": custom_recipe.project.id,
- }
-
- return {"error": "ok", "info": info}
-
- elif request.method == 'DELETE':
- custom_recipe.delete()
- return {"error": "ok"}
- else:
- return {"error": "Method %s is not supported" % request.method}
-
def customrecipe_download(request, pid, recipe_id):
recipe = get_object_or_404(CustomImageRecipe, pk=recipe_id)
@@ -2580,230 +1636,6 @@ if True:
return response
- def _traverse_dependents(next_package_id, rev_deps, all_current_packages, tree_level=0):
- """
- Recurse through reverse dependency tree for next_package_id.
- Limit the reverse dependency search to packages not already scanned,
- that is, not already in rev_deps.
- Limit the scan to a depth (tree_level) not exceeding the count of
- all packages in the custom image, and if that depth is exceeded
- return False, pop out of the recursion, and write a warning
- to the log, but this is unlikely, suggesting a dependency loop
- not caught by bitbake.
- On return, the input/output arg rev_deps is appended with queryset
- dictionary elements, annotated for use in the customimage template.
- The list has unsorted, but unique elements.
- """
- max_dependency_tree_depth = all_current_packages.count()
- if tree_level >= max_dependency_tree_depth:
- logger.warning(
- "The number of reverse dependencies "
- "for this package exceeds " + max_dependency_tree_depth +
- " and the remaining reverse dependencies will not be removed")
- return True
-
- package = CustomImagePackage.objects.get(id=next_package_id)
- dependents = \
- package.package_dependencies_target.annotate(
- name=F('package__name'),
- pk=F('package__pk'),
- size=F('package__size'),
- ).values("name", "pk", "size").exclude(
- ~Q(pk__in=all_current_packages)
- )
-
- for pkg in dependents:
- if pkg in rev_deps:
- # already seen, skip dependent search
- continue
-
- rev_deps.append(pkg)
- if (_traverse_dependents(
- pkg["pk"], rev_deps, all_current_packages, tree_level+1)):
- return True
-
- return False
-
- def _get_all_dependents(package_id, all_current_packages):
- """
- Returns sorted list of recursive reverse dependencies for package_id,
- as a list of dictionary items, by recursing through dependency
- relationships.
- """
- rev_deps = []
- _traverse_dependents(package_id, rev_deps, all_current_packages)
- rev_deps = sorted(rev_deps, key=lambda x: x["name"])
- return rev_deps
-
- @xhr_response
- def xhr_customrecipe_packages(request, recipe_id, package_id):
- """
- ReST API to add/remove packages to/from custom recipe.
-
- Entry point: /xhr_customrecipe/<recipe_id>/packages/<package_id>
-
- Methods:
- PUT - Add package to the recipe
- DELETE - Delete package from the recipe
- GET - Get package information
-
- Returns:
- {"error": "ok"}
- or
- {"error": <error message>}
- """
- try:
- recipe = CustomImageRecipe.objects.get(id=recipe_id)
- except CustomImageRecipe.DoesNotExist:
- return {"error": "Custom recipe with id=%s "
- "not found" % recipe_id}
-
- if package_id:
- try:
- package = CustomImagePackage.objects.get(id=package_id)
- except Package.DoesNotExist:
- return {"error": "Package with id=%s "
- "not found" % package_id}
-
- if request.method == 'GET':
- # If no package_id then list the current packages
- if not package_id:
- total_size = 0
- packages = recipe.get_all_packages().values("id",
- "name",
- "version",
- "size")
- for package in packages:
- package['size_formatted'] = \
- filtered_filesizeformat(package['size'])
- total_size += package['size']
-
- return {"error": "ok",
- "packages" : list(packages),
- "total" : len(packages),
- "total_size" : total_size,
- "total_size_formatted" :
- filtered_filesizeformat(total_size)
- }
- else:
- all_current_packages = recipe.get_all_packages()
-
- # Dependencies for package which aren't satisfied by the
- # current packages in the custom image recipe
- deps = package.package_dependencies_source.annotate(
- name=F('depends_on__name'),
- pk=F('depends_on__pk'),
- size=F('depends_on__size'),
- ).values("name", "pk", "size").filter(
- # There are two depends types we don't know why
- (Q(dep_type=Package_Dependency.TYPE_TRDEPENDS) |
- Q(dep_type=Package_Dependency.TYPE_RDEPENDS)) &
- ~Q(pk__in=all_current_packages)
- )
-
- # Reverse dependencies which are needed by packages that are
- # in the image. Recursive search providing all dependents,
- # not just immediate dependents.
- reverse_deps = _get_all_dependents(package_id, all_current_packages)
- total_size_deps = 0
- total_size_reverse_deps = 0
-
- for dep in deps:
- dep['size_formatted'] = \
- filtered_filesizeformat(dep['size'])
- total_size_deps += dep['size']
-
- for dep in reverse_deps:
- dep['size_formatted'] = \
- filtered_filesizeformat(dep['size'])
- total_size_reverse_deps += dep['size']
-
-
- return {"error": "ok",
- "id": package.pk,
- "name": package.name,
- "version": package.version,
- "unsatisfied_dependencies": list(deps),
- "unsatisfied_dependencies_size": total_size_deps,
- "unsatisfied_dependencies_size_formatted":
- filtered_filesizeformat(total_size_deps),
- "reverse_dependencies": list(reverse_deps),
- "reverse_dependencies_size": total_size_reverse_deps,
- "reverse_dependencies_size_formatted":
- filtered_filesizeformat(total_size_reverse_deps)}
-
- included_packages = recipe.includes_set.values_list('pk', flat=True)
-
- if request.method == 'PUT':
- # If we're adding back a package which used to be included in this
- # image all we need to do is remove it from the excludes
- if package.pk in included_packages:
- try:
- recipe.excludes_set.remove(package)
- return {"error": "ok"}
- except Package.DoesNotExist:
- return {"error":
- "Package %s not found in excludes but was in "
- "included list" % package.name}
-
- else:
- recipe.appends_set.add(package)
- # Make sure that package is not in the excludes set
- try:
- recipe.excludes_set.remove(package)
- except:
- pass
- # Add the dependencies we think will be added to the recipe
- # as a result of appending this package.
- # TODO this should recurse down the entire deps tree
- for dep in package.package_dependencies_source.all_depends():
- try:
- cust_package = CustomImagePackage.objects.get(
- name=dep.depends_on.name)
-
- recipe.includes_set.add(cust_package)
- try:
- # When adding the pre-requisite package, make
- # sure it's not in the excluded list from a
- # prior removal.
- recipe.excludes_set.remove(cust_package)
- except Package.DoesNotExist:
- # Don't care if the package had never been excluded
- pass
- except:
- logger.warning("Could not add package's suggested"
- "dependencies to the list")
-
- return {"error": "ok"}
-
- elif request.method == 'DELETE':
- try:
- # If we're deleting a package which is included we need to
- # Add it to the excludes list.
- if package.pk in included_packages:
- recipe.excludes_set.add(package)
- else:
- recipe.appends_set.remove(package)
- all_current_packages = recipe.get_all_packages()
- reverse_deps_dictlist = _get_all_dependents(package.pk, all_current_packages)
- ids = [entry['pk'] for entry in reverse_deps_dictlist]
- reverse_deps = CustomImagePackage.objects.filter(id__in=ids)
- for r in reverse_deps:
- try:
- if r.id in included_packages:
- recipe.excludes_set.add(r)
- else:
- recipe.appends_set.remove(r)
- except:
- pass
-
- return {"error": "ok"}
- except CustomImageRecipe.DoesNotExist:
- return {"error": "Tried to remove package that wasn't present"}
-
- else:
- return {"error": "Method %s is not supported" % request.method}
-
def importlayer(request, pid):
template = "importlayer.html"
context = {
@@ -2811,20 +1643,33 @@ if True:
}
return render(request, template, context)
+ # TODO merge with api pseudo api here is used for deps modal
@_template_renderer('layerdetails.html')
def layerdetails(request, pid, layerid):
project = Project.objects.get(pk=pid)
layer_version = Layer_Version.objects.get(pk=layerid)
- context = {'project' : project,
- 'layerversion' : layer_version,
- 'layerdeps' : {"list": [{"id": dep.id,
- "name": dep.layer.name,
- "layerdetailurl": reverse('layerdetails', args=(pid, dep.pk)),
- "vcs_url": dep.layer.vcs_url,
- "vcs_reference": dep.get_vcs_reference()} \
- for dep in layer_version.get_alldeps(project.id)]},
- 'projectlayers': map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=project))
+ project_layers = ProjectLayer.objects.filter(
+ project=project).values_list("layercommit_id",
+ flat=True)
+
+ context = {
+ 'project': project,
+ 'layer_source': LayerSource.types_dict(),
+ 'layerversion': layer_version,
+ 'layerdeps': {
+ "list": [
+ {
+ "id": dep.id,
+ "name": dep.layer.name,
+ "layerdetailurl": reverse('layerdetails',
+ args=(pid, dep.pk)),
+ "vcs_url": dep.layer.vcs_url,
+ "vcs_reference": dep.get_vcs_reference()
+ }
+ for dep in layer_version.get_alldeps(project.id)]
+ },
+ 'projectlayers': list(project_layers)
}
return context
@@ -2839,7 +1684,7 @@ if True:
vars_blacklist = {
'PARALLEL_MAKE','BB_NUMBER_THREADS',
'BB_DISKMON_DIRS','BB_NUMBER_THREADS','CVS_PROXY_HOST','CVS_PROXY_PORT',
- 'PARALLEL_MAKE','SSTATE_MIRRORS','TMPDIR',
+ 'PARALLEL_MAKE','TMPDIR',
'all_proxy','ftp_proxy','http_proxy ','https_proxy'
}
@@ -2887,7 +1732,7 @@ if True:
else:
context['dl_dir'] = ProjectVariable.objects.get(project = prj, name = "DL_DIR").value
context['dl_dir_defined'] = "1"
- except ProjectVariable.DoesNotExist,BuildEnvironment.DoesNotExist:
+ except (ProjectVariable.DoesNotExist, BuildEnvironment.DoesNotExist):
pass
try:
context['fstypes'] = ProjectVariable.objects.get(project = prj, name = "IMAGE_FSTYPES").value
@@ -2915,7 +1760,7 @@ if True:
else:
context['sstate_dir'] = ProjectVariable.objects.get(project = prj, name = "SSTATE_DIR").value
context['sstate_dir_defined'] = "1"
- except ProjectVariable.DoesNotExist, BuildEnvironment.DoesNotExist:
+ except (ProjectVariable.DoesNotExist, BuildEnvironment.DoesNotExist):
pass
return context
@@ -2936,12 +1781,20 @@ if True:
elif artifact_type == "imagefile":
file_name = Target_Image_File.objects.get(target__build = build, pk = artifact_id).file_name
- elif artifact_type == "buildartifact":
- file_name = BuildArtifact.objects.get(build = build, pk = artifact_id).file_name
+ elif artifact_type == "targetkernelartifact":
+ target = TargetKernelFile.objects.get(pk=artifact_id)
+ file_name = target.file_name
+
+ elif artifact_type == "targetsdkartifact":
+ target = TargetSDKFile.objects.get(pk=artifact_id)
+ file_name = target.file_name
elif artifact_type == "licensemanifest":
file_name = Target.objects.get(build = build, pk = artifact_id).license_manifest_path
+ elif artifact_type == "packagemanifest":
+ file_name = Target.objects.get(build = build, pk = artifact_id).package_manifest_path
+
elif artifact_type == "tasklogfile":
file_name = Task.objects.get(build = build, pk = artifact_id).logfile
@@ -2967,7 +1820,7 @@ if True:
)
if file_name and response_file_name:
- fsock = open(file_name, "r")
+ fsock = open(file_name, "rb")
content_type = MimeTypeFinder.get_mimetype(file_name)
response = HttpResponse(fsock, content_type = content_type)
@@ -2978,5 +1831,5 @@ if True:
return response
else:
return render(request, "unavailable_artifact.html")
- except ObjectDoesNotExist, IOError:
+ except (ObjectDoesNotExist, IOError):
return render(request, "unavailable_artifact.html")
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/widgets.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/widgets.py
index d2ef5d3db..026903d35 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/widgets.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/widgets.py
@@ -22,30 +22,41 @@
from django.views.generic import View, TemplateView
from django.views.decorators.cache import cache_control
from django.shortcuts import HttpResponse
-from django.http import HttpResponseBadRequest
-from django.core import serializers
from django.core.cache import cache
from django.core.paginator import Paginator, EmptyPage
from django.db.models import Q
-from orm.models import Project, ProjectLayer, Layer_Version
+from orm.models import Project, Build
from django.template import Context, Template
+from django.template import VariableDoesNotExist
+from django.template import TemplateSyntaxError
from django.core.serializers.json import DjangoJSONEncoder
from django.core.exceptions import FieldError
-from django.conf.urls import url, patterns
+from django.utils import timezone
+from toastergui.templatetags.projecttags import sectohms, get_tasks
+from toastergui.templatetags.projecttags import json as template_json
+from django.http import JsonResponse
+from django.core.urlresolvers import reverse
import types
import json
import collections
-import operator
import re
-import urllib
+
+try:
+ from urllib import unquote_plus
+except ImportError:
+ from urllib.parse import unquote_plus
import logging
logger = logging.getLogger("toaster")
-from toastergui.views import objtojson
from toastergui.tablefilter import TableFilterMap
+
+class NoFieldOrDataName(Exception):
+ pass
+
+
class ToasterTable(TemplateView):
def __init__(self, *args, **kwargs):
super(ToasterTable, self).__init__()
@@ -63,25 +74,20 @@ class ToasterTable(TemplateView):
self.empty_state = "Sorry - no data found"
self.default_orderby = ""
- # add the "id" column, undisplayable, by default
- self.add_column(title="Id",
- displayable=False,
- orderable=True,
- field_name="id")
-
# prevent HTTP caching of table data
- @cache_control(must_revalidate=True, max_age=0, no_store=True, no_cache=True)
+ @cache_control(must_revalidate=True,
+ max_age=0, no_store=True, no_cache=True)
def dispatch(self, *args, **kwargs):
return super(ToasterTable, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super(ToasterTable, self).get_context_data(**kwargs)
context['title'] = self.title
- context['table_name'] = type(self).__name__.lower()
+ context['table_name'] = type(self).__name__.lower()
+ context['empty_state'] = self.empty_state
return context
-
def get(self, request, *args, **kwargs):
if request.GET.get('format', None) == 'json':
@@ -102,8 +108,6 @@ class ToasterTable(TemplateView):
return super(ToasterTable, self).get(request, *args, **kwargs)
def get_filter_info(self, request, **kwargs):
- data = None
-
self.setup_filters(**kwargs)
search = request.GET.get("search", None)
@@ -117,13 +121,18 @@ class ToasterTable(TemplateView):
cls=DjangoJSONEncoder)
def setup_columns(self, *args, **kwargs):
- """ function to implement in the subclass which sets up the columns """
+ """ function to implement in the subclass which sets up
+ the columns """
pass
+
def setup_filters(self, *args, **kwargs):
- """ function to implement in the subclass which sets up the filters """
+ """ function to implement in the subclass which sets up the
+ filters """
pass
+
def setup_queryset(self, *args, **kwargs):
- """ function to implement in the subclass which sets up the queryset"""
+ """ function to implement in the subclass which sets up the
+ queryset"""
pass
def add_filter(self, table_filter):
@@ -137,7 +146,6 @@ class ToasterTable(TemplateView):
def add_column(self, title="", help_text="",
orderable=False, hideable=True, hidden=False,
field_name="", filter_name=None, static_data_name=None,
- displayable=True, computation=None,
static_data_template=None):
"""Add a column to the table.
@@ -155,18 +163,15 @@ class ToasterTable(TemplateView):
as data
"""
- self.columns.append({'title' : title,
- 'help_text' : help_text,
- 'orderable' : orderable,
- 'hideable' : hideable,
- 'hidden' : hidden,
- 'field_name' : field_name,
- 'filter_name' : filter_name,
+ self.columns.append({'title': title,
+ 'help_text': help_text,
+ 'orderable': orderable,
+ 'hideable': hideable,
+ 'hidden': hidden,
+ 'field_name': field_name,
+ 'filter_name': filter_name,
'static_data_name': static_data_name,
- 'static_data_template': static_data_template,
- 'displayable': displayable,
- 'computation': computation,
- })
+ 'static_data_template': static_data_template})
def set_column_hidden(self, title, hidden):
"""
@@ -190,8 +195,8 @@ class ToasterTable(TemplateView):
"""Utility function to render the static data template"""
context = {
- 'extra' : self.static_context_extra,
- 'data' : row,
+ 'extra': self.static_context_extra,
+ 'data': row,
}
context = Context(context)
@@ -216,7 +221,7 @@ class ToasterTable(TemplateView):
try:
filter_name, action_name = filters.split(':')
- action_params = urllib.unquote_plus(filter_value)
+ action_params = unquote_plus(filter_value)
except ValueError:
return
@@ -241,20 +246,25 @@ class ToasterTable(TemplateView):
if not hasattr(self.queryset.model, 'search_allowed_fields'):
raise Exception("Search fields aren't defined in the model %s"
- % self.queryset.model)
+ % self.queryset.model)
- search_queries = []
+ search_queries = None
for st in search_term.split(" "):
- q_map = [Q(**{field + '__icontains': st})
- for field in self.queryset.model.search_allowed_fields]
-
- search_queries.append(reduce(operator.or_, q_map))
-
- search_queries = reduce(operator.and_, search_queries)
+ queries = None
+ for field in self.queryset.model.search_allowed_fields:
+ query = Q(**{field + '__icontains': st})
+ if queries:
+ queries |= query
+ else:
+ queries = query
+
+ if search_queries:
+ search_queries &= queries
+ else:
+ search_queries = queries
self.queryset = self.queryset.filter(search_queries)
-
def get_data(self, request, **kwargs):
"""
Returns the data for the page requested with the specified
@@ -262,7 +272,8 @@ class ToasterTable(TemplateView):
filters: filter and action name, e.g. "outcome:build_succeeded"
filter_value: value to pass to the named filter+action, e.g. "on"
- (for a toggle filter) or "2015-12-11,2015-12-12" (for a date range filter)
+ (for a toggle filter) or "2015-12-11,2015-12-12"
+ (for a date range filter)
"""
page_num = request.GET.get("page", 1)
@@ -276,12 +287,12 @@ class ToasterTable(TemplateView):
# Make a unique cache name
cache_name = self.__class__.__name__
- for key, val in request.GET.iteritems():
+ for key, val in request.GET.items():
if key == 'nocache':
continue
cache_name = cache_name + str(key) + str(val)
- for key, val in kwargs.iteritems():
+ for key, val in kwargs.items():
cache_name = cache_name + str(key) + str(val)
# No special chars allowed in the cache name apart from dash
@@ -313,16 +324,16 @@ class ToasterTable(TemplateView):
page = paginator.page(1)
data = {
- 'total' : self.queryset.count(),
- 'default_orderby' : self.default_orderby,
- 'columns' : self.columns,
- 'rows' : [],
- 'error' : "ok",
+ 'total': self.queryset.count(),
+ 'default_orderby': self.default_orderby,
+ 'columns': self.columns,
+ 'rows': [],
+ 'error': "ok",
}
try:
- for row in page.object_list:
- #Use collection to maintain the order
+ for model_obj in page.object_list:
+ # Use collection to maintain the order
required_data = collections.OrderedDict()
for col in self.columns:
@@ -330,44 +341,73 @@ class ToasterTable(TemplateView):
if not field:
field = col['static_data_name']
if not field:
- raise Exception("Must supply a field_name or static_data_name for column %s.%s" % (self.__class__.__name__,col))
+ raise NoFieldOrDataName("Must supply a field_name or"
+ "static_data_name for column"
+ "%s.%s" %
+ (self.__class__.__name__, col)
+ )
+
# Check if we need to process some static data
if "static_data_name" in col and col['static_data_name']:
- required_data["static:%s" % col['static_data_name']] = self.render_static_data(col['static_data_template'], row)
-
# Overwrite the field_name with static_data_name
# so that this can be used as the html class name
-
col['field_name'] = col['static_data_name']
- # compute the computation on the raw data if needed
- model_data = row
- if col['computation']:
- model_data = col['computation'](row)
+ try:
+ # Render the template given
+ required_data[col['static_data_name']] = \
+ self.render_static_data(
+ col['static_data_template'], model_obj)
+ except (TemplateSyntaxError,
+ VariableDoesNotExist) as e:
+ logger.error("could not render template code"
+ "%s %s %s",
+ col['static_data_template'],
+ e, self.__class__.__name__)
+ required_data[col['static_data_name']] =\
+ '<!--error-->'
+
else:
- # Traverse to any foriegn key in the object hierachy
- for subfield in field.split("__"):
- if hasattr(model_data, subfield):
- model_data = getattr(model_data, subfield)
- # The field could be a function on the model so check
- # If it is then call it
+ # Traverse to any foriegn key in the field
+ # e.g. recipe__layer_version__name
+ model_data = None
+
+ if "__" in field:
+ for subfield in field.split("__"):
+ if not model_data:
+ # The first iteration is always going to
+ # be on the actual model object instance.
+ # Subsequent ones are on the result of
+ # that. e.g. forieng key objects
+ model_data = getattr(model_obj,
+ subfield)
+ else:
+ model_data = getattr(model_data,
+ subfield)
+
+ else:
+ model_data = getattr(model_obj,
+ col['field_name'])
+
+ # We might have a model function as the field so
+ # call it to return the data needed
if isinstance(model_data, types.MethodType):
- model_data = model_data()
+ model_data = model_data()
- required_data[col['field_name']] = model_data
+ required_data[col['field_name']] = model_data
data['rows'].append(required_data)
except FieldError:
# pass it to the user - programming-error here
raise
- data = json.dumps(data, indent=2, default=objtojson)
+
+ data = json.dumps(data, indent=2, cls=DjangoJSONEncoder)
cache.set(cache_name, data, 60*30)
return data
-
class ToasterTypeAhead(View):
""" A typeahead mechanism to support the front end typeahead widgets """
MAX_RESULTS = 6
@@ -388,34 +428,142 @@ class ToasterTypeAhead(View):
error = "ok"
search_term = request.GET.get("search", None)
- if search_term == None:
+ if search_term is None:
# We got no search value so return empty reponse
- return response({'error' : error , 'results': []})
+ return response({'error': error, 'results': []})
try:
prj = Project.objects.get(pk=kwargs['pid'])
except KeyError:
prj = None
- results = self.apply_search(search_term, prj, request)[:ToasterTypeAhead.MAX_RESULTS]
+ results = self.apply_search(search_term,
+ prj,
+ request)[:ToasterTypeAhead.MAX_RESULTS]
if len(results) > 0:
try:
self.validate_fields(results[0])
- except MissingFieldsException as e:
+ except self.MissingFieldsException as e:
error = e
- data = { 'results' : results,
- 'error' : error,
- }
+ data = {'results': results,
+ 'error': error}
return response(data)
def validate_fields(self, result):
- if 'name' in result == False or 'detail' in result == False:
- raise MissingFieldsException("name and detail are required fields")
+ if 'name' in result is False or 'detail' in result is False:
+ raise self.MissingFieldsException(
+ "name and detail are required fields")
def apply_search(self, search_term, prj):
""" Override this function to implement search. Return an array of
dictionaries with a minium of a name and detail field"""
pass
+
+
+class MostRecentBuildsView(View):
+ def _was_yesterday_or_earlier(self, completed_on):
+ now = timezone.now()
+ delta = now - completed_on
+
+ if delta.days >= 1:
+ return True
+
+ return False
+
+ def get(self, request, *args, **kwargs):
+ """
+ Returns a list of builds in JSON format.
+ """
+ project = None
+
+ project_id = request.GET.get('project_id', None)
+ if project_id:
+ try:
+ project = Project.objects.get(pk=project_id)
+ except:
+ # if project lookup fails, assume no project
+ pass
+
+ recent_build_objs = Build.get_recent(project)
+ recent_builds = []
+
+ for build_obj in recent_build_objs:
+ dashboard_url = reverse('builddashboard', args=(build_obj.pk,))
+ buildtime_url = reverse('buildtime', args=(build_obj.pk,))
+ rebuild_url = \
+ reverse('xhr_buildrequest', args=(build_obj.project.pk,))
+ cancel_url = \
+ reverse('xhr_buildrequest', args=(build_obj.project.pk,))
+
+ build = {}
+ build['id'] = build_obj.pk
+ build['dashboard_url'] = dashboard_url
+
+ buildrequest_id = None
+ if hasattr(build_obj, 'buildrequest'):
+ buildrequest_id = build_obj.buildrequest.pk
+ build['buildrequest_id'] = buildrequest_id
+
+ build['recipes_parsed_percentage'] = \
+ int((build_obj.recipes_parsed /
+ build_obj.recipes_to_parse) * 100)
+
+ tasks_complete_percentage = 0
+ if build_obj.outcome in (Build.SUCCEEDED, Build.FAILED):
+ tasks_complete_percentage = 100
+ elif build_obj.outcome == Build.IN_PROGRESS:
+ tasks_complete_percentage = build_obj.completeper()
+ build['tasks_complete_percentage'] = tasks_complete_percentage
+
+ build['state'] = build_obj.get_state()
+
+ build['errors'] = build_obj.errors.count()
+ build['dashboard_errors_url'] = dashboard_url + '#errors'
+
+ build['warnings'] = build_obj.warnings.count()
+ build['dashboard_warnings_url'] = dashboard_url + '#warnings'
+
+ build['buildtime'] = sectohms(build_obj.timespent_seconds)
+ build['buildtime_url'] = buildtime_url
+
+ build['rebuild_url'] = rebuild_url
+ build['cancel_url'] = cancel_url
+
+ build['is_default_project_build'] = build_obj.project.is_default
+
+ build['build_targets_json'] = \
+ template_json(get_tasks(build_obj.target_set.all()))
+
+ # convert completed_on time to user's timezone
+ completed_on = timezone.localtime(build_obj.completed_on)
+
+ completed_on_template = '%H:%M'
+ if self._was_yesterday_or_earlier(completed_on):
+ completed_on_template = '%d/%m/%Y ' + completed_on_template
+ build['completed_on'] = completed_on.strftime(
+ completed_on_template)
+
+ targets = []
+ target_objs = build_obj.get_sorted_target_list()
+ for target_obj in target_objs:
+ if target_obj.task:
+ targets.append(target_obj.target + ':' + target_obj.task)
+ else:
+ targets.append(target_obj.target)
+ build['targets'] = ' '.join(targets)
+
+ # abbreviated form of the full target list
+ abbreviated_targets = ''
+ num_targets = len(targets)
+ if num_targets > 0:
+ abbreviated_targets = targets[0]
+ if num_targets > 1:
+ abbreviated_targets += (' +%s' % (num_targets - 1))
+ build['targets_abbreviated'] = abbreviated_targets
+
+ recent_builds.append(build)
+
+ return JsonResponse(recent_builds, safe=False)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/builddelete.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/builddelete.py
index ff93e549d..0bef8d410 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/builddelete.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/builddelete.py
@@ -15,7 +15,7 @@ class Command(BaseCommand):
try:
b = Build.objects.get(pk = bid)
except ObjectDoesNotExist:
- print 'build %s does not exist, skipping...' %(bid)
+ print('build %s does not exist, skipping...' %(bid))
continue
# theoretically, just b.delete() would suffice
# however SQLite runs into problems when you try to
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/buildslist.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/buildslist.py
index cad987fd9..8dfef0aa0 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/buildslist.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/buildslist.py
@@ -10,4 +10,4 @@ class Command(NoArgsCommand):
def handle_noargs(self,**options):
for b in Build.objects.all():
- print "%d: %s %s %s" % (b.pk, b.machine, b.distro, ",".join([x.target for x in b.target_set.all()]))
+ print("%d: %s %s %s" % (b.pk, b.machine, b.distro, ",".join([x.target for x in b.target_set.all()])))
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/get-dburl.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/get-dburl.py
deleted file mode 100644
index 22b3eb79e..000000000
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/get-dburl.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from toastermain.settings import getDATABASE_URL
-from django.core.management.base import NoArgsCommand
-
-class Command(NoArgsCommand):
- args = ""
- help = "get database url"
-
- def handle_noargs(self,**options):
- print getDATABASE_URL()
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/perf.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/perf.py
index 71a48e95d..6b450bbdf 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/perf.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/management/commands/perf.py
@@ -25,7 +25,7 @@ class Command(BaseCommand):
info = self.url_info(full_url)
status_code = info[0]
load_time = info[1]
- print 'Trying \'' + full_url + '\', ' + str(status_code) + ', ' + str(load_time)
+ print('Trying \'' + full_url + '\', ' + str(status_code) + ', ' + str(load_time))
def get_full_url(self, url_patt, url_root_res):
full_url = str(url_patt).split('^')[1].replace('$>', '').replace('(?P<file_path>(?:/[', '/bin/busybox').replace('.*', '')
@@ -54,5 +54,5 @@ class Command(BaseCommand):
def error(self, *args):
for arg in args:
- print >>sys.stderr, arg,
- print >>sys.stderr
+ print(arg, end=' ', file=sys.stderr)
+ print(file=sys.stderr)
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings.py
index 74ab60462..3dfa2b223 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings.py
@@ -21,7 +21,7 @@
# Django settings for Toaster project.
-import os, re
+import os
DEBUG = True
TEMPLATE_DEBUG = DEBUG
@@ -38,14 +38,19 @@ ADMINS = (
MANAGERS = ADMINS
+TOASTER_SQLITE_DEFAULT_DIR = os.path.join(os.environ.get('TOASTER_DIR', ''),
+ 'build')
+
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
- 'NAME': 'toaster.sqlite', # Or path to database file if using sqlite3.
+ # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ 'ENGINE': 'django.db.backends.sqlite3',
+ # DB name or full path to database file if using sqlite3.
+ 'NAME': "%s/toaster.sqlite" % TOASTER_SQLITE_DEFAULT_DIR,
'USER': '',
'PASSWORD': '',
- 'HOST': '127.0.0.1', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
- 'PORT': '3306', # Set to empty string for default.
+ #'HOST': '127.0.0.1', # e.g. mysql server
+ #'PORT': '3306', # e.g. mysql port
}
}
@@ -55,58 +60,6 @@ DATABASES = {
if 'sqlite' in DATABASES['default']['ENGINE']:
DATABASES['default']['OPTIONS'] = { 'timeout': 20 }
-# Reinterpret database settings if we have DATABASE_URL environment variable defined
-
-if 'DATABASE_URL' in os.environ:
- dburl = os.environ['DATABASE_URL']
-
- if dburl.startswith('sqlite3://'):
- result = re.match('sqlite3://(.*)', dburl)
- if result is None:
- raise Exception("ERROR: Could not read sqlite database url: %s" % dburl)
- DATABASES['default'] = {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': result.group(1),
- 'USER': '',
- 'PASSWORD': '',
- 'HOST': '',
- 'PORT': '',
- }
- elif dburl.startswith('mysql://'):
- # URL must be in this form: mysql://user:pass@host:port/name
- result = re.match(r"mysql://([^:]*):([^@]*)@([^:]*):(\d*)/([^/]*)", dburl)
- if result is None:
- raise Exception("ERROR: Could not read mysql database url: %s" % dburl)
- DATABASES['default'] = {
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME': result.group(5),
- 'USER': result.group(1),
- 'PASSWORD': result.group(2),
- 'HOST': result.group(3),
- 'PORT': result.group(4),
- }
- else:
- raise Exception("FIXME: Please implement missing database url schema for url: %s" % dburl)
-
-
-# Allows current database settings to be exported as a DATABASE_URL environment variable value
-
-def getDATABASE_URL():
- d = DATABASES['default']
- if d['ENGINE'] == 'django.db.backends.sqlite3':
- if d['NAME'] == ':memory:':
- return 'sqlite3://:memory:'
- elif d['NAME'].startswith("/"):
- return 'sqlite3://' + d['NAME']
- return "sqlite3://" + os.path.join(os.getcwd(), d['NAME'])
-
- elif d['ENGINE'] == 'django.db.backends.mysql':
- return "mysql://" + d['USER'] + ":" + d['PASSWORD'] + "@" + d['HOST'] + ":" + d['PORT'] + "/" + d['NAME']
-
- raise Exception("FIXME: Please implement missing database url schema for engine: %s" % d['ENGINE'])
-
-
-
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
@@ -134,17 +87,16 @@ else:
try:
import pytz
from pytz.exceptions import UnknownTimeZoneError
- pass
try:
if pytz.timezone(zonename) is not None:
- zonefilelist[hashlib.md5(open(filepath).read()).hexdigest()] = zonename
- except UnknownTimeZoneError, ValueError:
+ zonefilelist[hashlib.md5(open(filepath, 'rb').read()).hexdigest()] = zonename
+ except UnknownTimeZoneError as ValueError:
# we expect timezone failures here, just move over
pass
except ImportError:
- zonefilelist[hashlib.md5(open(filepath).read()).hexdigest()] = zonename
+ zonefilelist[hashlib.md5(open(filepath, 'rb').read()).hexdigest()] = zonename
- TIME_ZONE = zonefilelist[hashlib.md5(open('/etc/localtime').read()).hexdigest()]
+ TIME_ZONE = zonefilelist[hashlib.md5(open('/etc/localtime', 'rb').read()).hexdigest()]
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
@@ -321,7 +273,7 @@ currentdir = os.path.dirname(__file__)
for t in os.walk(os.path.dirname(currentdir)):
modulename = os.path.basename(t[0])
#if we have a virtualenv skip it to avoid incorrect imports
- if os.environ.has_key('VIRTUAL_ENV') and os.environ['VIRTUAL_ENV'] in t[0]:
+ if 'VIRTUAL_ENV' in os.environ and os.environ['VIRTUAL_ENV'] in t[0]:
continue
if ("views.py" in t[2] or "models.py" in t[2]) and not modulename in INSTALLED_APPS:
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings_test.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings_test.py
new file mode 100644
index 000000000..a32271157
--- /dev/null
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/settings_test.py
@@ -0,0 +1,41 @@
+#
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# BitBake Toaster Implementation
+#
+# Copyright (C) 2016 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Django settings for Toaster project.
+
+# Settings overlay to use for running tests
+# DJANGO_SETTINGS_MODULE=toastermain.settings-test
+
+from toastermain.settings import *
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': '/tmp/toaster-test-db.sqlite',
+ 'TEST': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': '/tmp/toaster-test-db.sqlite',
+ }
+ }
+}
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/urls.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/urls.py
index 534679dc5..1f8599edc 100644
--- a/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/urls.py
+++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastermain/urls.py
@@ -71,7 +71,7 @@ import os
currentdir = os.path.dirname(__file__)
for t in os.walk(os.path.dirname(currentdir)):
#if we have a virtualenv skip it to avoid incorrect imports
- if os.environ.has_key('VIRTUAL_ENV') and os.environ['VIRTUAL_ENV'] in t[0]:
+ if 'VIRTUAL_ENV' in os.environ and os.environ['VIRTUAL_ENV'] in t[0]:
continue
if "urls.py" in t[2] and t[0] != currentdir:
@@ -84,7 +84,7 @@ for t in os.walk(os.path.dirname(currentdir)):
if not conflict:
urlpatterns.insert(0, url(r'^' + modulename + '/', include ( modulename + '.urls')))
else:
- logger.warn("Module \'%s\' has a regexp conflict, was not added to the urlpatterns" % modulename)
+ logger.warning("Module \'%s\' has a regexp conflict, was not added to the urlpatterns" % modulename)
from pprint import pformat
#logger.debug("urlpatterns list %s", pformat(urlpatterns))
OpenPOWER on IntegriCloud