From 998d011cd308d2d959ccab1e5b8ea92cc732616f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 9 Oct 2013 15:40:23 +0200 Subject: [PATCH 0001/2518] Initial commit --- db/fic2014.sql | 100 + htdocs/.onyx | 1 + htdocs/index.php | 174 + onyx/ban.list | 0 onyx/cache/templates/cache/cache | 0 onyx/cache/templates/compile/compile | 0 onyx/config/sample.root.xml | 60 + onyx/db/sample.profile.php | 10 + onyx/include/common.php | 28 + onyx/include/functions.php | 96 + onyx/lang/en.xml | 5 + onyx/lang/fr/contact.json | 1 + onyx/lang/fr/erreurs.json | 1 + onyx/lang/fr/global.json | 1 + onyx/lang/fr/publication.json | 1 + onyx/lang/fr/register.json | 1 + onyx/lang/fr/tickets.json | 1 + onyx/lang/fr/userinfos.json | 1 + onyx/load.php | 167 + onyx/log/php.log | 0 onyx/modules/bbcode/main.php | 60 + onyx/modules/captcha/fonts/0.ttfdd | Bin 0 -> 24216 bytes onyx/modules/captcha/fonts/1.ttf | Bin 0 -> 69380 bytes onyx/modules/captcha/main.php | 121 + onyx/modules/captcha/mots.list | 3834 +++++++++++++++++ onyx/modules/chconfig/__config.class.php | 28 + onyx/modules/chconfig/chconfig.class.php | 110 + onyx/modules/chconfig/chmodules.class.php | 57 + onyx/modules/chconfig/main.php | 65 + onyx/modules/db/main.php | 28 + onyx/modules/db/mysql.class.php | 171 + onyx/modules/db/postgresql.class.php | 169 + onyx/modules/lang/main.php | 96 + onyx/modules/mail/class.phpmailer.php | 2320 ++++++++++ onyx/modules/mail/class.pop3.php | 407 ++ onyx/modules/mail/class.smtp.php | 814 ++++ .../mail/language/phpmailer.lang-ar.php | 26 + .../mail/language/phpmailer.lang-br.php | 23 + .../mail/language/phpmailer.lang-ca.php | 24 + .../mail/language/phpmailer.lang-ch.php | 24 + .../mail/language/phpmailer.lang-cz.php | 23 + .../mail/language/phpmailer.lang-de.php | 24 + .../mail/language/phpmailer.lang-dk.php | 23 + .../mail/language/phpmailer.lang-en.php | 23 + .../mail/language/phpmailer.lang-es.php | 23 + .../mail/language/phpmailer.lang-et.php | 24 + .../mail/language/phpmailer.lang-fi.php | 24 + .../mail/language/phpmailer.lang-fo.php | 25 + .../mail/language/phpmailer.lang-fr.php | 23 + .../mail/language/phpmailer.lang-hu.php | 23 + .../mail/language/phpmailer.lang-it.php | 26 + .../mail/language/phpmailer.lang-ja.php | 24 + .../mail/language/phpmailer.lang-nl.php | 23 + .../mail/language/phpmailer.lang-no.php | 23 + .../mail/language/phpmailer.lang-pl.php | 23 + .../mail/language/phpmailer.lang-ro.php | 24 + .../mail/language/phpmailer.lang-ru.php | 23 + .../mail/language/phpmailer.lang-se.php | 23 + .../mail/language/phpmailer.lang-tr.php | 24 + .../mail/language/phpmailer.lang-zh.php | 23 + .../mail/language/phpmailer.lang-zh_cn.php | 24 + onyx/modules/mail/main.php | 38 + onyx/modules/modules.xml | 93 + onyx/modules/pistage/main.php | 34 + onyx/modules/session/main.php | 20 + onyx/modules/session/mysql.class.php | 161 + onyx/modules/session/postgresql.class.php | 153 + onyx/modules/templates/config/config | 0 onyx/modules/templates/main.php | 29 + .../modules/templates/smarty/Smarty.class.php | 1520 +++++++ .../templates/smarty/SmartyBC.class.php | 460 ++ onyx/modules/templates/smarty/debug.tpl | 133 + .../templates/smarty/plugins/block.php.php | 27 + .../smarty/plugins/block.textformat.php | 113 + .../smarty/plugins/function.counter.php | 78 + .../smarty/plugins/function.cycle.php | 106 + .../smarty/plugins/function.fetch.php | 214 + .../plugins/function.html_checkboxes.php | 216 + .../smarty/plugins/function.html_image.php | 159 + .../smarty/plugins/function.html_options.php | 176 + .../smarty/plugins/function.html_radios.php | 200 + .../plugins/function.html_select_date.php | 394 ++ .../plugins/function.html_select_time.php | 366 ++ .../smarty/plugins/function.html_table.php | 177 + .../smarty/plugins/function.mailto.php | 152 + .../smarty/plugins/function.math.php | 87 + .../smarty/plugins/function.popup.php | 118 + .../smarty/plugins/function.popup_init.php | 38 + .../smarty/plugins/function.text.php | 33 + .../smarty/plugins/modifier.capitalize.php | 65 + .../templates/smarty/plugins/modifier.cat.php | 31 + .../plugins/modifier.count_characters.php | 29 + .../plugins/modifier.count_paragraphs.php | 26 + .../plugins/modifier.count_sentences.php | 27 + .../smarty/plugins/modifier.count_words.php | 25 + .../smarty/plugins/modifier.countdown.php | 33 + .../smarty/plugins/modifier.date_format.php | 65 + .../plugins/modifier.debug_print_var.php | 105 + .../smarty/plugins/modifier.default.php | 29 + .../smarty/plugins/modifier.download.php | 26 + .../smarty/plugins/modifier.ereg.php | 30 + .../smarty/plugins/modifier.escape.php | 188 + .../smarty/plugins/modifier.exploderes.php | 32 + .../smarty/plugins/modifier.gravatar.php | 29 + .../smarty/plugins/modifier.indent.php | 28 + .../smarty/plugins/modifier.lower.php | 30 + .../smarty/plugins/modifier.nl2br.php | 35 + .../templates/smarty/plugins/modifier.nom.php | 30 + .../smarty/plugins/modifier.noprint.php | 24 + .../smarty/plugins/modifier.regex_replace.php | 55 + .../smarty/plugins/modifier.replace.php | 33 + .../smarty/plugins/modifier.separenombre.php | 29 + .../plugins/modifier.separerNombres.php | 28 + .../plugins/modifier.separernombres.php | 28 + .../smarty/plugins/modifier.spacify.php | 27 + .../smarty/plugins/modifier.splitwords.php | 38 + .../smarty/plugins/modifier.sprintf.php | 43 + .../smarty/plugins/modifier.status.php | 106 + .../smarty/plugins/modifier.string_format.php | 27 + .../smarty/plugins/modifier.strip.php | 31 + .../smarty/plugins/modifier.strip_tags.php | 31 + .../smarty/plugins/modifier.temps.php | 45 + .../smarty/plugins/modifier.translatedate.php | 19 + .../smarty/plugins/modifier.truncate.php | 59 + .../smarty/plugins/modifier.txtcateg.php | 26 + .../smarty/plugins/modifier.ucfirst.php | 27 + .../smarty/plugins/modifier.upper.php | 30 + .../templates/smarty/plugins/modifier.url.php | 48 + .../smarty/plugins/modifier.wordwrap.php | 29 + .../smarty/plugins/modifiercompiler.cat.php | 30 + .../modifiercompiler.count_characters.php | 33 + .../modifiercompiler.count_paragraphs.php | 28 + .../modifiercompiler.count_sentences.php | 28 + .../plugins/modifiercompiler.count_words.php | 32 + .../plugins/modifiercompiler.default.php | 35 + .../plugins/modifiercompiler.escape.php | 125 + .../plugins/modifiercompiler.from_charset.php | 34 + .../plugins/modifiercompiler.indent.php | 32 + .../smarty/plugins/modifiercompiler.lower.php | 31 + .../plugins/modifiercompiler.noprint.php | 25 + .../modifiercompiler.string_format.php | 26 + .../smarty/plugins/modifiercompiler.strip.php | 33 + .../plugins/modifiercompiler.strip_tags.php | 33 + .../plugins/modifiercompiler.to_charset.php | 34 + .../plugins/modifiercompiler.unescape.php | 51 + .../smarty/plugins/modifiercompiler.upper.php | 30 + .../plugins/modifiercompiler.wordwrap.php | 46 + .../plugins/outputfilter.trimwhitespace.php | 94 + .../plugins/shared.escape_special_chars.php | 51 + .../plugins/shared.literal_compiler_param.php | 33 + .../smarty/plugins/shared.make_timestamp.php | 42 + .../smarty/plugins/shared.mb_str_replace.php | 55 + .../smarty/plugins/shared.mb_unicode.php | 48 + .../smarty/plugins/shared.mb_wordwrap.php | 83 + .../variablefilter.htmlspecialchars.php | 21 + .../sysplugins/smarty_cacheresource.php | 381 ++ .../smarty_cacheresource_custom.php | 237 + .../smarty_cacheresource_keyvaluestore.php | 463 ++ .../sysplugins/smarty_config_source.php | 95 + .../smarty_internal_cacheresource_file.php | 266 ++ .../smarty_internal_compile_append.php | 53 + .../smarty_internal_compile_assign.php | 88 + .../smarty_internal_compile_block.php | 277 ++ .../smarty_internal_compile_break.php | 77 + .../smarty_internal_compile_call.php | 130 + .../smarty_internal_compile_capture.php | 98 + .../smarty_internal_compile_config_load.php | 85 + .../smarty_internal_compile_continue.php | 78 + .../smarty_internal_compile_debug.php | 43 + .../smarty_internal_compile_eval.php | 73 + .../smarty_internal_compile_extends.php | 133 + .../smarty_internal_compile_for.php | 151 + .../smarty_internal_compile_foreach.php | 231 + .../smarty_internal_compile_function.php | 165 + .../sysplugins/smarty_internal_compile_if.php | 207 + .../smarty_internal_compile_include.php | 215 + .../smarty_internal_compile_include_php.php | 108 + .../smarty_internal_compile_insert.php | 142 + .../smarty_internal_compile_ldelim.php | 41 + .../smarty_internal_compile_nocache.php | 73 + ..._internal_compile_private_block_plugin.php | 87 + ...ternal_compile_private_function_plugin.php | 73 + ...arty_internal_compile_private_modifier.php | 140 + ..._compile_private_object_block_function.php | 88 + ...ternal_compile_private_object_function.php | 79 + ...ernal_compile_private_print_expression.php | 156 + ...ernal_compile_private_registered_block.php | 113 + ...al_compile_private_registered_function.php | 81 + ...ernal_compile_private_special_variable.php | 111 + .../smarty_internal_compile_rdelim.php | 41 + .../smarty_internal_compile_section.php | 203 + .../smarty_internal_compile_setfilter.php | 72 + .../smarty_internal_compile_while.php | 94 + .../smarty_internal_compilebase.php | 176 + .../sysplugins/smarty_internal_config.php | 302 ++ .../smarty_internal_config_file_compiler.php | 144 + .../smarty_internal_configfilelexer.php | 622 +++ .../smarty_internal_configfileparser.php | 921 ++++ .../sysplugins/smarty_internal_data.php | 551 +++ .../sysplugins/smarty_internal_debug.php | 206 + .../sysplugins/smarty_internal_filter.php | 89 + .../smarty_internal_filter_handler.php | 70 + .../smarty_internal_function_call_handler.php | 55 + .../smarty_internal_get_include_path.php | 48 + .../smarty_internal_nocache_insert.php | 53 + .../sysplugins/smarty_internal_parsetree.php | 395 ++ .../sysplugins/smarty_internal_register.php | 156 + .../smarty_internal_resource_eval.php | 94 + .../smarty_internal_resource_extends.php | 162 + .../smarty_internal_resource_file.php | 90 + .../smarty_internal_resource_php.php | 114 + .../smarty_internal_resource_registered.php | 95 + .../smarty_internal_resource_stream.php | 76 + .../smarty_internal_resource_string.php | 96 + ...smarty_internal_smartytemplatecompiler.php | 127 + .../sysplugins/smarty_internal_template.php | 692 +++ .../smarty_internal_templatebase.php | 811 ++++ .../smarty_internal_templatecompilerbase.php | 662 +++ .../smarty_internal_templatelexer.php | 1203 ++++++ .../smarty_internal_templateparser.php | 3254 ++++++++++++++ .../sysplugins/smarty_internal_utility.php | 830 ++++ .../sysplugins/smarty_internal_wrapper.php | 131 + .../sysplugins/smarty_internal_write_file.php | 88 + .../smarty/sysplugins/smarty_resource.php | 857 ++++ .../sysplugins/smarty_resource_custom.php | 96 + .../sysplugins/smarty_resource_recompiled.php | 36 + .../sysplugins/smarty_resource_uncompiled.php | 44 + .../smarty/sysplugins/smarty_security.php | 459 ++ onyx/require/cache.php | 35 + onyx/require/env.php | 49 + onyx/require/parse.php | 73 + onyx/require/str.php | 109 + onyx/tpl/bootstrap/bootstrap | 0 233 files changed, 36893 insertions(+) create mode 100644 db/fic2014.sql create mode 100644 htdocs/.onyx create mode 100644 htdocs/index.php create mode 100644 onyx/ban.list create mode 100644 onyx/cache/templates/cache/cache create mode 100644 onyx/cache/templates/compile/compile create mode 100644 onyx/config/sample.root.xml create mode 100644 onyx/db/sample.profile.php create mode 100644 onyx/include/common.php create mode 100644 onyx/include/functions.php create mode 100644 onyx/lang/en.xml create mode 100644 onyx/lang/fr/contact.json create mode 100644 onyx/lang/fr/erreurs.json create mode 100644 onyx/lang/fr/global.json create mode 100644 onyx/lang/fr/publication.json create mode 100644 onyx/lang/fr/register.json create mode 100644 onyx/lang/fr/tickets.json create mode 100644 onyx/lang/fr/userinfos.json create mode 100644 onyx/load.php create mode 100644 onyx/log/php.log create mode 100644 onyx/modules/bbcode/main.php create mode 100644 onyx/modules/captcha/fonts/0.ttfdd create mode 100644 onyx/modules/captcha/fonts/1.ttf create mode 100644 onyx/modules/captcha/main.php create mode 100755 onyx/modules/captcha/mots.list create mode 100644 onyx/modules/chconfig/__config.class.php create mode 100644 onyx/modules/chconfig/chconfig.class.php create mode 100644 onyx/modules/chconfig/chmodules.class.php create mode 100644 onyx/modules/chconfig/main.php create mode 100644 onyx/modules/db/main.php create mode 100644 onyx/modules/db/mysql.class.php create mode 100644 onyx/modules/db/postgresql.class.php create mode 100644 onyx/modules/lang/main.php create mode 100644 onyx/modules/mail/class.phpmailer.php create mode 100644 onyx/modules/mail/class.pop3.php create mode 100644 onyx/modules/mail/class.smtp.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ar.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-br.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ca.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ch.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-cz.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-de.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-dk.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-en.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-es.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-et.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-fi.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-fo.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-fr.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-hu.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-it.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ja.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-nl.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-no.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-pl.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ro.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ru.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-se.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-tr.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-zh.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-zh_cn.php create mode 100644 onyx/modules/mail/main.php create mode 100644 onyx/modules/modules.xml create mode 100644 onyx/modules/pistage/main.php create mode 100644 onyx/modules/session/main.php create mode 100644 onyx/modules/session/mysql.class.php create mode 100644 onyx/modules/session/postgresql.class.php create mode 100644 onyx/modules/templates/config/config create mode 100644 onyx/modules/templates/main.php create mode 100644 onyx/modules/templates/smarty/Smarty.class.php create mode 100644 onyx/modules/templates/smarty/SmartyBC.class.php create mode 100644 onyx/modules/templates/smarty/debug.tpl create mode 100644 onyx/modules/templates/smarty/plugins/block.php.php create mode 100644 onyx/modules/templates/smarty/plugins/block.textformat.php create mode 100644 onyx/modules/templates/smarty/plugins/function.counter.php create mode 100644 onyx/modules/templates/smarty/plugins/function.cycle.php create mode 100644 onyx/modules/templates/smarty/plugins/function.fetch.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_checkboxes.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_image.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_options.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_radios.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_select_date.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_select_time.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_table.php create mode 100644 onyx/modules/templates/smarty/plugins/function.mailto.php create mode 100644 onyx/modules/templates/smarty/plugins/function.math.php create mode 100644 onyx/modules/templates/smarty/plugins/function.popup.php create mode 100644 onyx/modules/templates/smarty/plugins/function.popup_init.php create mode 100644 onyx/modules/templates/smarty/plugins/function.text.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.capitalize.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.cat.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.count_characters.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.count_paragraphs.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.count_sentences.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.count_words.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.countdown.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.date_format.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.debug_print_var.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.default.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.download.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.ereg.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.escape.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.exploderes.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.gravatar.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.indent.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.lower.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.nl2br.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.nom.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.noprint.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.regex_replace.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.replace.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.separenombre.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.separerNombres.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.separernombres.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.spacify.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.splitwords.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.sprintf.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.status.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.string_format.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.strip.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.strip_tags.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.temps.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.translatedate.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.truncate.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.txtcateg.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.ucfirst.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.upper.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.url.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.wordwrap.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.cat.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.count_characters.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.count_paragraphs.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.count_sentences.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.count_words.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.default.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.escape.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.from_charset.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.indent.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.lower.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.noprint.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.string_format.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.strip.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.strip_tags.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.to_charset.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.unescape.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.upper.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.wordwrap.php create mode 100644 onyx/modules/templates/smarty/plugins/outputfilter.trimwhitespace.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.escape_special_chars.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.literal_compiler_param.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.make_timestamp.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.mb_str_replace.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.mb_unicode.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.mb_wordwrap.php create mode 100644 onyx/modules/templates/smarty/plugins/variablefilter.htmlspecialchars.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_cacheresource.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_cacheresource_custom.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_cacheresource_keyvaluestore.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_config_source.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_cacheresource_file.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_append.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_assign.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_block.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_break.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_call.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_capture.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_config_load.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_continue.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_debug.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_eval.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_extends.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_for.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_foreach.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_function.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_if.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_include.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_include_php.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_insert.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_ldelim.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_nocache.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_block_plugin.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_function_plugin.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_modifier.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_object_block_function.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_object_function.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_print_expression.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_registered_block.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_registered_function.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_special_variable.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_rdelim.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_section.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_setfilter.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_while.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compilebase.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_config.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_config_file_compiler.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_configfilelexer.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_configfileparser.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_data.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_debug.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_filter.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_filter_handler.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_function_call_handler.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_get_include_path.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_nocache_insert.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_parsetree.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_register.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_eval.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_extends.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_file.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_php.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_registered.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_stream.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_string.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_smartytemplatecompiler.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_template.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_templatebase.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_templatecompilerbase.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_templatelexer.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_templateparser.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_utility.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_wrapper.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_write_file.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_resource.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_resource_custom.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_resource_recompiled.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_resource_uncompiled.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_security.php create mode 100644 onyx/require/cache.php create mode 100644 onyx/require/env.php create mode 100644 onyx/require/parse.php create mode 100644 onyx/require/str.php create mode 100644 onyx/tpl/bootstrap/bootstrap diff --git a/db/fic2014.sql b/db/fic2014.sql new file mode 100644 index 00000000..38d9e326 --- /dev/null +++ b/db/fic2014.sql @@ -0,0 +1,100 @@ +-- phpMyAdmin SQL Dump +-- version 3.5.1 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: Oct 09, 2013 at 03:38 PM +-- Server version: 5.5.32-log +-- PHP Version: 5.4.9--pl0-gentoo + +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + +-- +-- Database: `fic2014` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `exercices` +-- + +CREATE TABLE IF NOT EXISTS `exercices` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_theme` int(10) unsigned NOT NULL, + `name` varchar(255) COLLATE utf16_unicode_ci NOT NULL, + `difficulty` tinyint(3) unsigned NOT NULL, + `points` smallint(6) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `exercice_dependancies` +-- + +CREATE TABLE IF NOT EXISTS `exercice_dependancies` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_exercice` int(10) unsigned NOT NULL, + `id_dependence` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `sessions` +-- + +CREATE TABLE IF NOT EXISTS `sessions` ( + `session` binary(32) NOT NULL, + `uid` binary(16) NOT NULL, + `time` int(11) NOT NULL, + `ip` varbinary(16) NOT NULL, + `var` varchar(9999) COLLATE utf8_unicode_ci NOT NULL, + `level` tinyint(2) NOT NULL, + `active` enum('1','0') COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`session`) +) ENGINE=MEMORY DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `solved` +-- + +CREATE TABLE IF NOT EXISTS `solved` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_user` int(10) unsigned NOT NULL, + `id_exercice` int(10) unsigned NOT NULL, + `time` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `themes` +-- + +CREATE TABLE IF NOT EXISTS `themes` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) COLLATE utf16_unicode_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `users` +-- + +CREATE TABLE IF NOT EXISTS `users` ( + `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `username` varchar(255) COLLATE utf16_unicode_ci NOT NULL, + `password` binary(64) NOT NULL, + `auth_level` tinyint(1) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; diff --git a/htdocs/.onyx b/htdocs/.onyx new file mode 100644 index 00000000..9e6e10a7 --- /dev/null +++ b/htdocs/.onyx @@ -0,0 +1 @@ +../onyx/load.php diff --git a/htdocs/index.php b/htdocs/index.php new file mode 100644 index 00000000..ebe38cc3 --- /dev/null +++ b/htdocs/index.php @@ -0,0 +1,174 @@ +level > 0) +{ + if ($SESS->level&1) + { + switch($p) + { + case "adm_users": + include("admin/users.php"); + break; + } + } + + if ($SESS->level&2) + { + switch($p) + { + case "articles": + include("articles/articles.php"); + break; + + case "articles_prod": + include("articles/production.php"); + break; + } + } + + if ($SESS->level&4) + { + switch($p) + { + case "palettes": + include("articles/palettes.php"); + break; + + case "palettes_besoins": + include("articles/needs.php"); + break; + + case "prod_couts": + include("production/costs.php"); + break; + + case "stocks_besoins": + include("materials/needs.php"); + break; + + case "stocks_etat": + include("materials/etat.php"); + break; + + case "transport": + include("materials/transport.php"); + break; + } + } + + if ($SESS->level&16) + { + switch($p) + { + case "commandes": + include("materials/commandes.php"); + break; + + case "stocks_besoins": + include("materials/needs.php"); + break; + + case "transport": + include("materials/transport.php"); + break; + } + } + + if ($SESS->level&8) + { + switch($p) + { + case "prod_resume": + include("articles/needs.php"); + break; + + case "prod_entry": + include("production/entry.php"); + break; + } + } + + switch($p) + { + case "": + $_GET["p"] = ""; + case "accueil": + include("users/accueil.php"); + break; + + case "disconnect": + include("public/login.php"); + break; + } +} + +if (empty($page)) // Public pages +{ + switch($p) + { + case "": + $_GET["p"] = ""; + case "login": + include("public/login.php"); + break; + + case "forgotpasswd": + include("public/forgotpasswd.php"); + break; + + case "403": + $template->assign("err", 403); + $page = "404"; + break; + case "404": + $template->assign("err", 404); + $page = "404"; + break; + case "5mail": + include("mail.php"); + exit; + case "500": + $template->assign("err", 500); + $page = "404"; + break; + } +} + +if (empty($page)) +{ + $template->assign("err", 404); + $template->display("404.tpl"); +} +else +{ + $ALERTS = array(); + $nbAlert = @count($SESS->values["alerts"]); + if ($nbAlert > 0) + { + for ($i = 0; $i < $nbAlert; $i++) + { + if ($SESS->values["alerts"][$i]->page == $page) + { + $ALERTS[] = $SESS->values["alerts"][$i]; + unset($SESS->values["alerts"][$i]); + $i--; $nbAlert--; + $SESS->values["alerts"] = array_values($SESS->values["alerts"]); + } + } + $SESS->put(); + } + $template->assign("ALERTS", $ALERTS); + + $template->display($page.".tpl"); +} diff --git a/onyx/ban.list b/onyx/ban.list new file mode 100644 index 00000000..e69de29b diff --git a/onyx/cache/templates/cache/cache b/onyx/cache/templates/cache/cache new file mode 100644 index 00000000..e69de29b diff --git a/onyx/cache/templates/compile/compile b/onyx/cache/templates/compile/compile new file mode 100644 index 00000000..e69de29b diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml new file mode 100644 index 00000000..61d79f2e --- /dev/null +++ b/onyx/config/sample.root.xml @@ -0,0 +1,60 @@ + + + + ]]> + + + 0 + 1 + 6143 + Europe/Paris + + text/html;charset=utf-8 + + + 0 + 0 + 1 + 1 + 0 + 0 + 64M + 1 + + 1 + + fr_FR.UTF8 + fr.UTF8 + fr_FR.UTF-8 + fr.UTF-8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/onyx/db/sample.profile.php b/onyx/db/sample.profile.php new file mode 100644 index 00000000..1ad73643 --- /dev/null +++ b/onyx/db/sample.profile.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/onyx/include/common.php b/onyx/include/common.php new file mode 100644 index 00000000..05d87757 --- /dev/null +++ b/onyx/include/common.php @@ -0,0 +1,28 @@ +values["connected"]) && !defined("xCSRF")) + define("xCSRF", true); + +require_once("functions.php"); //Inclusion des principales fonctions + +//On charge la session +$SESS = new Session(); + +$template = new Template(); + +$template->assign("ERRmessage", false); +$template->assign("auth_lvl", $SESS->level); +$template->assign("SESS", $SESS->values); + +if (!empty($LANG)) + $template->assign("LANG", $LANG); + +//Evite les attaques CSRF +if ($SESS->level > 2 && !empty($_SERVER["HTTP_REFERER"]) && !(preg_match('#^http://'.$_SERVER['HTTP_HOST'].'#', $_SERVER["HTTP_REFERER"]) && defined("xCSRF"))) +{ + elog("Possibilité d'attaque CSRF\n".var_export($_REQUEST, TRUE), 2); + unset($_POST, $_GET); + $_GET = $_POST = array(); +} +?> \ No newline at end of file diff --git a/onyx/include/functions.php b/onyx/include/functions.php new file mode 100644 index 00000000..dfdd80f4 --- /dev/null +++ b/onyx/include/functions.php @@ -0,0 +1,96 @@ +AddAddress($to); + $mail->Subject = $subject; + $mail->Body = $body; + + return $mail->Send(); +} + +function erreur($message, $color = "error") +{ + global $template; + + $template->assign('ERRmessage', $message); + $template->assign('ERRcolor', $color); +} + +function format_url($string) +{ + $string = trim($string); + + if ( ctype_digit($string) ) + { + return $string; + } + else + { + // replace accented chars + $accents = '/&([A-Za-z]{1,2})(grave|acute|circ|cedil|uml|lig);/'; + $string_encoded = htmlentities($string,ENT_NOQUOTES,'UTF-8'); + + $string = preg_replace($accents,'$1',$string_encoded); + + // clean out the rest + $replace = array('([\40\'/])','([^a-zA-Z0-9-])','(-{2,})'); + $with = array('-','','-'); + $string = preg_replace($replace,$with,$string); + } + + return strtolower($string); +} + +function pagination($nbPages, $page, $link = "documents-recents-") +{ + $nbPages++; + $cntPages = array(); + if ($nbPages < 10) + { + for ($i = 1 ; $i <= $nbPages ; $i++) + $cntPages[] = $i; + } + else + { + for ($i = 1 ; $i <= 4 ; $i++) + $cntPages[] = $i; + if (6 != max(6, $page)) + $cntPages[] = "..."; + for ($i = max(6, $page) - 1 ; $i < min(max(6, $page) + 3, $nbPages - 2) ; $i++) + $cntPages[] = $i; + if ($nbPages - 2 != max(6, $page) + 3 && $nbPages - 2 != $i) + $cntPages[] = "..."; + for ($i = $nbPages - 2 ; $i <= $nbPages ; $i++) + $cntPages[] = $i; + } + + $out = ""; + foreach($cntPages as $p) + { + if ($p == "...") + $out .= " ... "; + else + $out .= ' '.$p.' '; + } + + return '<<'.$out.'>>'; +} + +function eregmenu($pattern, $string) +{ + return preg_match("#".$pattern."#ui", $string); +} + +?> \ No newline at end of file diff --git a/onyx/lang/en.xml b/onyx/lang/en.xml new file mode 100644 index 00000000..6f95bc53 --- /dev/null +++ b/onyx/lang/en.xml @@ -0,0 +1,5 @@ + + + Hello + Good bye + \ No newline at end of file diff --git a/onyx/lang/fr/contact.json b/onyx/lang/fr/contact.json new file mode 100644 index 00000000..6ee3fe78 --- /dev/null +++ b/onyx/lang/fr/contact.json @@ -0,0 +1 @@ +{"title":"Nous contacter","1":{"reponses":{"2":"Je suis acheteur","3":"Je suis vendeur","4":"Je suis annonceur","5":"Je souhaite signaler une faute d'orthographe ou un bug pr\u00e9sent sur le site"}},"2":{"intitule":"Raison de votre contact","reponses":{"2.1":"Je n'ai pas b\u00e9n\u00e9fici\u00e9 de mon document gratuit apr\u00e8s cinq achats","2.2":"Je n'ai pas re\u00e7u mon document apr\u00e8s paiement","2.3":"Je ne parviens pas \u00e0 me connecter \u00e0 mon compte","form2.4":"Je me suis fais voler mon compte","2.5":"Je n'arrive pas \u00e0 lire le document que j'ai achet\u00e9","2.6":"Autre"}},"2.1":{"intitule":"Si vous avez achet\u00e9 cinq documents sur Discis, nous vous offrons un document d'une valeur de 1,80 euros. Seuls les documents de cette valeur vous seront accessibles gratuitements apr\u00e8s l'achat de cinq documents.
\nPour b\u00e9n\u00e9ficier de cette offre, connectez-vous \u00e0 votre compte puis allez sur la page du document que vous souhaitez acqu\u00e9rir, celui-ci sera disponible gratuitement !\nNous ne faisons pas de remise sur les documents sup\u00e9rieurs \u00e0 1,80euros.","reponses":{"0":"Retourner \u00e0 l'accueil","2.1.1":"Apr\u00e8s avoir effectu\u00e9 les manipulations d\u00e9crites ci-dessus, je n'ai toujours pas obtenu mon document gratuit"}},"2.1.1":{"intitule":"Pour comptabiliser vos diff\u00e9rents achats, il est n\u00e9cessaire que vous poss\u00e9diez un compte et que vous y soyez connect\u00e9s lors de l'achat des documents.
Nous ne pouvons rien faire dans le cas contraire.
Si vous ne poss\u00e8dez pas de compte, vous ne pouvez malheuresement pas b\u00e9n\u00e9ficier de notre programme de fid\u00e9lit\u00e9.","reponses":{"0":"Retourner \u00e0 l'acceuil","form2.1.1.1":"Je poss\u00e8de un compte Discis et j'\u00e9tais connect\u00e9 lors de l'achat de mes documents"}},"2.3":{"intitule":"Si vous ne parvenez pas \u00e0 vous connecter \u00e0 votre compte, v\u00e9rifiez tout d'abord que ce probl\u00e8me n'est pas d'ordre g\u00e9n\u00e9ral en consultant notre blog des d\u00e9veloppeurs dans la rubrique probl\u00e8mes techniques.","reponses":{"0":"Retourner \u00e0 l'accueil","2.3.1":"Aucun probl\u00e8me n'est signal\u00e9 concernant les connections aux comptes utilisateurs sur le blog des d\u00e9veloppeurs"}},"2.3.1":{"intitule":"Vous pouvez r\u00e9cup\u00e9rer votre mot de pass en cliquant sur le lien \"mot de pass oubli\u00e9\" en dessous du formulaire de connection du compte. Un mail vous sera alors envoy\u00e9 sur l'adresse que vous nous avez fourni lors de votre inscription.","reponses":{"0":"Retourner \u00e0 l'accueil","2.5.1":"Je n'arrive pas \u00e0 utiliser 7-zip","form2.5.2":"Le fichier est illisibe et semble corrompu"}},"form2.4":["test","test2"],"3":{"intitule":"Raison de votre contacte","reponses":{"3.1":"Un de mes documents a \u00e9t\u00e9 plagi\u00e9","3.2":"Mes documents ne sont toujours pas publi\u00e9s","3.3":"Je n'ai toujours pas re\u00e7u mon paiement","3.4":"Je souhaite supprimer un document","3.5":"Je ne parviens pas \u00e0 me connecter \u00e0 mon compte","3.6":"Autre"}},"3.1":{"intitule":"Si vous vous \u00eates rendu compte que certains de vos documents ont \u00e9t\u00e9 plagi\u00e9s sur un site internet tiers, vous pouvez en g\u00e9n\u00e9ral contacter les webmasters du dit site via un formulaire de contact.\n Voici un mod\u00e8le de lettre que vous pouvez soumettre pour faire valoir vos droits :

\n

\nBonjour,

\nJe vous informe que le document [ins\u00e9rez le titre du document] disponible sur votre site internet \u00e0 cette adresse [ins\u00e9rez l'adresse du plagiat] est un document dont je suis l'auteur que j'ai publi\u00e9 sur le site internet discis.fr le [ins\u00e9rer la date de publication de votre document] \u00e0 l'adresse suivante : [ins\u00e9rer l'adresse discis de votre document]. Je vous demande de bien vouloir supprimer ce document plagi\u00e9 de votre base de donn\u00e9e.

\nCordialement<\/p>\nSi vous ne recevez aucune r\u00e9ponse d'ici deux semaines, cliquez sur le bouton ci-dessous.","reponses":{"0":"Retourner \u00e0 l'accueil","form3.1.1":"Le site internet du document plagi\u00e9 n'a pas r\u00e9pondu \u00e0 mon mail"}},"3.2":{"intitule":"Le temps de traitement de vos documents d\u00e9pend du nombre de documents que nous recevons. De plus, afin de garantir la vente de documents de qualit\u00e9s, nous prenons un certain temps \u00e0 lire un \u00e0 un chaque document re\u00e7u et \u00e0 le soumettre \u00e0 notre logiciel anti-plagiat.
Tout ceci prend beaucoup de temps et nous nous excusons par avance pour les d\u00e9lais qui peuvent \u00eatre longs dans certains cas.
Cependant, si votre document a \u00e9t\u00e9 envoy\u00e9 il y a plus d'un mois, il a sans doute \u00e9t\u00e9 \"oubli\u00e9\" par notre comit\u00e9 de lecture.","reponses":{"0":"Retourner \u00e0 l'accueil","form3.2.1":"Aucun probl\u00e8me n'est signal\u00e9 convernant des retards de paiement ce mois-ci sur le blog des d\u00e9veloppeurs"}}} \ No newline at end of file diff --git a/onyx/lang/fr/erreurs.json b/onyx/lang/fr/erreurs.json new file mode 100644 index 00000000..b975bbc0 --- /dev/null +++ b/onyx/lang/fr/erreurs.json @@ -0,0 +1 @@ +{"403":{"title":"Erreur 403","subtitle":"Accès réglementé","content":"Vous n'\u00eates pas autoris\u00e9 \u00e0 acc\u00e9der \u00e0 cette page."},"404":{"title":"Erreur 404","subtitle":"Page introuvable","content":"La page à laquelle vous tentez d'accéder n'existe pas ou l'adresse que vous avez tapée est incorrecte."},"500":{"title":"Erreur 500","subtitle":"Serveur indisponible","content":"Le serveur est actuellement dans l'incapacit\u00e9 de repondre \u00e0 votre requ\u00eate.

Veuillez recommencer plus tard."}} diff --git a/onyx/lang/fr/global.json b/onyx/lang/fr/global.json new file mode 100644 index 00000000..c8a47985 --- /dev/null +++ b/onyx/lang/fr/global.json @@ -0,0 +1 @@ +{"date":"d\/m\/Y \u00e0 H:i","rssfeed":"Flux Atom des nouvelles","forgotpsw":"Mot de passe oubli\u00e9 ...","continue":"Continuer","send":"Envoyer","login":{"connect":"Ok","disconnect":"D\u00e9connexion"},"menu":{"0":{"accueil":"Accueil","publier":"Publier","inscription":"S'inscrire","contact":"Contact"},"1":{"conditions-generales":"Conditions g\u00e9n\u00e9rales"},"2":{"accueil":"Accueil","mon-compte":"Mon compte","statistiques":"Statistiques","":"


","publier":"Publier","mes-documents-publies":"Mes documents publi\u00e9s","mes-documents-en-attente":"Mes documents en attente %s"," ":"
","contact":"Contact"},"4":{"kor-docs-en-correction":"Documents en correction %s","kor-docs-en-attente":"Documents en attente %s"},"6":{"adm-controldocs":"Documents \u00e0 controler %s","kor-docs-en-correction":"Documents en correction %s","kor-docs-en-attente":"Documents en attente %s","":"
","adm-prise-de-controle":"Prendre le controle d'un compte","adm-pubs":"Modifier les publicit\u00e9s","adm-news":"Modifier les news"," ":"
","tickets":"Tickets %s"}},"footer":{"annonceurs":"Annonceurs","conditions-generales":"Conditions g\u00e9n\u00e9rales","plan":"Plan du site"}} \ No newline at end of file diff --git a/onyx/lang/fr/publication.json b/onyx/lang/fr/publication.json new file mode 100644 index 00000000..7251a212 --- /dev/null +++ b/onyx/lang/fr/publication.json @@ -0,0 +1 @@ +{"titre0":"Publication de documents","mails":{"pubOk":{"subject":"[Discis] Publication de votre document","body":"Bonjour,\n\nNous avons le plaisir de vous informer que votre document %s, soumis \u00e0 notre \u00e9quipe le %s, vient d\u2019\u00eatre publi\u00e9 sur Discis.\nVotre document est propos\u00e9 \u00e0 la vente pour %s ; il est disponible \u00e0 cette adresse : http:\/\/www.discis.fr\/document-%s. Si vous d\u00e9sirez apporter des modifications \u00e0 votre document, connectez-vous dans votre espace personnel dans la rubrique \"Mes documents publi\u00e9s\" (http:\/\/www.discis.fr\/mes-documents-publies).\n\nCordialement,"},"pubMod":{"subject":"[Discis] Publication de votre document","body":"Bonjour,\n\nVotre document %s soumis le %s a retenu notre intention. Cependant, nous ne l\u2019avons pas encore publi\u00e9 pour la raison suivante\u00a0:\n\n%s\n\nPour effectuer les modifications n\u00e9cessaires, connectez-vous \u00e0 votre compte \u00e0 la rubrique \"Mes documents en attente\" (http:\/\/www.discis.fr\/mes-documents-en-attente).\n\nCordialement,"},"pubNo":{"subject":"[Discis] Publication de votre document","body":"Bonjour,\n\nNous sommes d\u00e9sol\u00e9 de vous informer que votre document %s soumis le %s ne sera pas publi\u00e9 sur Discis. Le motif est le suivant\u00a0: %s.\n\nNous vous encourageons \u00e0 modifier ce document pour le soumettre \u00e0 nouveau \u00e0 notre \u00e9quipe.\n\nCordialement,"}}} \ No newline at end of file diff --git a/onyx/lang/fr/register.json b/onyx/lang/fr/register.json new file mode 100644 index 00000000..bfa03627 --- /dev/null +++ b/onyx/lang/fr/register.json @@ -0,0 +1 @@ +{"title":"Inscription","helpCaptcha":"Si vous ne parvennez pas \u00e0 voir cette image, contactez un administrateur.","msgOk":"Votre inscription a \u00e9t\u00e9 r\u00e9alis\u00e9e avec succ\u00e8s.
Bienvenue sur Discis !","chPswd":"Votre mot de passe a \u00e9t\u00e9 r\u00e9initialis\u00e9 avec succ\u00e8s.","button":"S'inscrire","err0":"Le nom d'utilisateur comporte des catact\u00e8res invalides ou est trop court ou trop long !","err1":"Veuillez compl\u00e9ter tous les champs","err2":"Le texte que vous avez recopi\u00e9 ne correspond pas au contenu de l'image !","err3":"Le mot de passe et sa conformation sont diff\u00e9rents !","err4":"Le mot de passe est trop court ! Il doit contenir au moins 8 caract\u00e8res.","err5":"L'adresse \u00e9lectronique indiqu\u00e9e ne semble pas valide.","err6":"Le nom d'utilisateur que vous avez choisit existe d\u00e9j\u00e0 ou votre adresse \u00e9lectronique est d\u00e9j\u00e0 associ\u00e9e avec un autre compte.","mail":{"subject":"[Discis] Validation de votre inscription","body":"Soyez le bienvenu sur Discis !\n\nNous vous souhaitons beaucoup de succ\u00e8s avec la vente de vos documents ou la gestion de vos achats. Nous tenons \u00e0 vous informer que nous sommes \u00e0 disposition si vous avez besoin d'aide. Ainsi, vous pouvez nous contacter \u00e0 tout moment via la page contact du site.\n\nMerci de vous \u00eatre enregistr\u00e9,"},"tip":[{"title":"Bienvenue sur Discis !","content":"Votre compte Discis vous permettra de :\n @@ -31,5 +35,8 @@ {$ERRmessage} {/if} + +
{block name=content}{/block} +
{/block} diff --git a/onyx/tpl/bootstrap/public/score.tpl b/onyx/tpl/bootstrap/public/score.tpl index 8c6ef25c..2fea7aee 100644 --- a/onyx/tpl/bootstrap/public/score.tpl +++ b/onyx/tpl/bootstrap/public/score.tpl @@ -1,11 +1,22 @@ {extends file="layout.tpl"} {block name=head} - + {/block} {block name=content} +
+
+
    +
  • 00
  • +
  • :
  • +
  • 00
  • +
  • :
  • +
  • 00
  • +
+
+

TOP #10

@@ -56,7 +67,7 @@

Example

-

This is a example

+

This is a example

This is a example

This is a example

This is a example

@@ -103,8 +114,21 @@ {block name=end} + {/block} From bed471d75a086c7b621a11175286b510e537c7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Tue, 22 Oct 2013 08:16:02 +0200 Subject: [PATCH 0038/2518] New router and associated pages --- htdocs/index.php | 145 +++++++++--------- nginx.conf | 2 +- onyx/config/sample.root.xml | 12 -- onyx/include/common.php | 15 +- .../common/{User.class.php => Team.class.php} | 0 onyx/include/public/home.php | 17 +- onyx/include/public/team.php | 16 ++ onyx/include/team/change.php | 6 + onyx/include/team/exercice.php | 6 + onyx/include/team/home.php | 8 + onyx/include/team/summary.php | 6 + onyx/include/team/team.php | 16 ++ 12 files changed, 134 insertions(+), 115 deletions(-) rename onyx/include/common/{User.class.php => Team.class.php} (100%) create mode 100644 onyx/include/public/team.php create mode 100644 onyx/include/team/change.php create mode 100644 onyx/include/team/exercice.php create mode 100644 onyx/include/team/home.php create mode 100644 onyx/include/team/summary.php create mode 100644 onyx/include/team/team.php diff --git a/htdocs/index.php b/htdocs/index.php index ad2248b4..fcd65efe 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -2,112 +2,107 @@ //Inclusion de l'API Onyx require_once(trim(file_get_contents('./.onyx'))); +define("SALT_USER", "connected"); +define("SALT_ADMIN", "admin"); + //On active le débogage si l'on est sur le domaine de debug if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "fic" || $_SERVER["SERVER_NAME"] == "atlantis.chen.li") define("DEBUG", true); //Chargement de tout le nécessaire pour le site -require_once("common.php"); +//require_once("common.php"); -$p = strtolower(gpc("p")); +$n = preg_match_all("#[^/]+#", strtolower(gpc("p")), $out); +$p = $out[0]; -if (empty($page) && $SESS->level > 0) +// Admin part +if ($p[0] == SALT_ADMIN) { - if ($SESS->level > 1) + if ($n <= 1) + $page = require("admin/home.php"); + else { - switch($p) + switch($p[1]) { - case "exercices/import/": - case "exercices/import": - include("admin/import_exercices.php"); + case "exercices/import/": + case "exercices/import": + $page = require("admin/import_exercices.php"); break; - case "users": - case "users/": - include("admin/list_users.php"); + case "users": + case "users/": + $page = require("admin/list_users.php"); break; - case "users/import": - case "users/import/": - include("admin/import_users.php"); + case "users/import": + case "users/import/": + $page = require("admin/import_users.php"); break; } } - - switch($p) - { - case "": - $_GET["p"] = ""; - case "accueil": - include("users/accueil.php"); - break; - - case "disconnect": - include("public/login.php"); - break; - } } -if (empty($page)) // Public pages +// Known users +else if ($p[0] == SALT_USER) { - switch($p) + $connected = true; + + if ($n <= 1) + $page = require("team/home.php"); + else { - case "": - $_GET["p"] = ""; - case "home": - include("public/home.php"); - break; + $TEAM = $p[1]; - case "login": - include("public/login.php"); - break; + if ($n <= 2) + $page = require("team/team.php"); + else + { + switch($p[2]) + { + case "change/": + case "change": + $page = require("team/change.php"); + break; - case "score": - include("public/score.php"); - break; + case "summary": + case "summary/": + $page = require("team/summary.php"); + break; + } - case "403": - $template->assign("err", 403); - $page = "404"; - break; - case "404": - $template->assign("err", 404); - $page = "404"; - break; - case "5mail": - include("mail.php"); - exit; - case "500": - $template->assign("err", 500); - $page = "404"; - break; + // SALT/$team/$theme + if (empty($page)) + { + $THEME = $p[2]; + + if ($n == 4) + { + $EXERCICE = $p[3]; + $page = require("team/exercice.php"); + } + } + } } } +// Public part +else +{ + if ($n == 0) + $page = require("public/home.php"); + else if ($n == 1) + { + $TEAM = $p[0]; + + $page = require("public/team.php"); + } +} + +// No page here...? if (empty($page)) { $template->assign("err", 404); $template->display("404.tpl"); } else -{ - $ALERTS = array(); - $nbAlert = @count($SESS->values["alerts"]); - if ($nbAlert > 0) - { - for ($i = 0; $i < $nbAlert; $i++) - { - if ($SESS->values["alerts"][$i]->page == $page) - { - $ALERTS[] = $SESS->values["alerts"][$i]; - unset($SESS->values["alerts"][$i]); - $i--; $nbAlert--; - $SESS->values["alerts"] = array_values($SESS->values["alerts"]); - } - } - $SESS->put(); - } - $template->assign("ALERTS", $ALERTS); - $template->display($page.".tpl"); -} diff --git a/nginx.conf b/nginx.conf index e85f1569..02cc969c 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,6 +1,6 @@ server { listen 80; - listen [::]:80; + listen [::]:80 ipv6only=on; server_name fic fic.p0m.fr fic.nemunai.re; access_log /var/log/nginx/fic.access_log; diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index 5f3a4696..e6291018 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -38,16 +38,6 @@ - - - - - - - - - @@ -55,7 +45,5 @@ - - diff --git a/onyx/include/common.php b/onyx/include/common.php index b1397253..6754e327 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -7,26 +7,13 @@ if (empty($sess->values["connected"]) && !defined("xCSRF")) require_once("functions.php"); //Inclusion des principales fonctions require_once("common/Exercice.class.php"); +require_once("common/Team.class.php"); require_once("common/Theme.class.php"); -require_once("common/User.class.php"); - -//On charge la session -$SESS = new Session(); $template = new Template(); $template->assign("ERRmessage", false); -$template->assign("auth_lvl", $SESS->level); -$template->assign("SESS", $SESS->values); $template->assign("END", $VAR['end_challenge'] - time()); if (!empty($LANG)) $template->assign("LANG", $LANG); - -//Evite les attaques CSRF -if ($SESS->level > 2 && !empty($_SERVER["HTTP_REFERER"]) && !(preg_match('#^http://'.$_SERVER['HTTP_HOST'].'#', $_SERVER["HTTP_REFERER"]) && defined("xCSRF"))) -{ - elog("Possibilité d'attaque CSRF\n".var_export($_REQUEST, TRUE), 2); - unset($_POST, $_GET); - $_GET = $_POST = array(); -} diff --git a/onyx/include/common/User.class.php b/onyx/include/common/Team.class.php similarity index 100% rename from onyx/include/common/User.class.php rename to onyx/include/common/Team.class.php diff --git a/onyx/include/public/home.php b/onyx/include/public/home.php index 3e8231ad..a1542da3 100644 --- a/onyx/include/public/home.php +++ b/onyx/include/public/home.php @@ -2,16 +2,7 @@ if(!defined('ONYX')) exit; -$t = Team::get_teams(); -foreach ($t as $tt){ - var_dump ($tt->get_username()); -} - -if ($SESS->level < 1) -{ - $page = "public/home"; -} -else -{ - $page = "users/home"; -} +$template->assign("teams", Team::get_teams()); +$template->assign("top", Team::get_top()); + +return "public/home"; diff --git a/onyx/include/public/team.php b/onyx/include/public/team.php new file mode 100644 index 00000000..dfd91661 --- /dev/null +++ b/onyx/include/public/team.php @@ -0,0 +1,16 @@ +assign("team", $team); + + return "public/team"; +} +catch($e) +{ + return "404"; +} diff --git a/onyx/include/team/change.php b/onyx/include/team/change.php new file mode 100644 index 00000000..8a234331 --- /dev/null +++ b/onyx/include/team/change.php @@ -0,0 +1,6 @@ +assign("teams", Team::get_teams()); +$template->assign("top", Team::get_top()); + +return "users/home"; diff --git a/onyx/include/team/summary.php b/onyx/include/team/summary.php new file mode 100644 index 00000000..3ab8aeca --- /dev/null +++ b/onyx/include/team/summary.php @@ -0,0 +1,6 @@ +assign("team", $team); + + return "team/team"; +} +catch($e) +{ + return "404"; +} From 39d5e64ee286c815375754db206eb7f89869d9e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Tue, 22 Oct 2013 08:19:51 +0200 Subject: [PATCH 0039/2518] Hotfix: notice in router --- htdocs/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index fcd65efe..57e1f8f3 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -10,13 +10,13 @@ if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "fic" | define("DEBUG", true); //Chargement de tout le nécessaire pour le site -//require_once("common.php"); +require_once("common.php"); $n = preg_match_all("#[^/]+#", strtolower(gpc("p")), $out); $p = $out[0]; // Admin part -if ($p[0] == SALT_ADMIN) +if ($n && $p[0] == SALT_ADMIN) { if ($n <= 1) $page = require("admin/home.php"); @@ -43,7 +43,7 @@ if ($p[0] == SALT_ADMIN) } // Known users -else if ($p[0] == SALT_USER) +else if ($n && $p[0] == SALT_USER) { $connected = true; From 0035b984ff7f4cba56aa7b002704fcc86838c3ce Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Tue, 22 Oct 2013 08:31:12 +0200 Subject: [PATCH 0040/2518] Modify feedfortests.sql to match with new DB --- db/feedfortests.sql | 289 +++++++++++++++++--------------------------- 1 file changed, 112 insertions(+), 177 deletions(-) diff --git a/db/feedfortests.sql b/db/feedfortests.sql index d3d24598..36fbafe2 100644 --- a/db/feedfortests.sql +++ b/db/feedfortests.sql @@ -1,4 +1,69 @@ -INSERT INTO `fic2014`.`themes` ( +INSERT INTO `fic`.`users` ( +`id` , +`username` , +`password` , +`auth_level` , +`firstname` , +`lastname` , +`company` +) +VALUES ( +'1', 'Alpha', '2134s65df423sdf132sdg431dsg', '1', 'Alph', 'A', 'Epitra' +), ( +'2', 'Beta', '2134s65df423sef132sdg431dsg', '1', 'Bet', 'A', 'Epitra' +), ( +'3', 'Charli', '2134s45df423sdf132sdg431dsg', '1', 'Charl', 'I', 'Epitra' +), ( +'4', 'Delta', '2134s65df423sdf131sdg431dsg', '1', 'Delt', 'A', 'Epitra' +), ( +'5', 'Echo', '2134s65df423sdf132sdg431dfg', '1', 'Ech', 'O', 'Epitra' +), ( +'6', 'Foxtrot', '2134s65df423shf132sdg431dsg', '1', 'Fox', 'Trot', 'Epitra' +), ( +'7', 'Golf', '2134s65df423sdf1f2sdg431dsg', '1', 'Gol', 'F', 'Epitra' +), ( +'8', 'Hotel', '2134s65df423sdf13zsdg431dsg', '1', 'Hot', 'El', 'Epitra' +), ( +'9', 'India', '2134s65df423sdf13csdg431dsg', '1', 'Ind', 'Ia', 'Epitra' +), ( +'10', 'Juliet', '2134s65df4q3sdf132sdg431dsg', '1', 'Jule', 'Yer', 'Epitra' +), ( +'11', 'Kevlar', '2134s65df423sdf132s2g431dsg', '1', 'Krev', 'Lard', 'Epitra' +), ( +'12', 'Lambda', '2134s65df423sdf132sdg401dsg', '1', 'Lamb', 'Ada', 'Epitra' +), ( +'13' , 'Mike', '2134s65df423sdf132sdg401dsg', '1', 'Mi', 'Ke', 'Epitra' +), ( +'14' , 'November', '2134s65df423sdf132sdg401dsg', '1', 'Nov', 'Ember', 'Epitra' +), ( +'15' , 'Oscar', '2134s65df423sdf132sdg401dsg', '1', 'Os', 'Car', 'Epitra' +), ( +'16' , 'Papa', '2134s65df423sdf132sdg401dsg', '1', 'Pa', 'Pa', 'Epitra' +), ( +'17' , 'Quebec', '2134s65df423sdf132sdg401dsg', '1', 'Que', 'Bec', 'Epitra' +), ( +'18' , 'Romeo', '2134s65df423sdf132sdg401dsg', '1', 'Rom', 'Eo', 'Epitra' +), ( +'19' , 'Sierra', '2134s65df423sdf132sdg401dsg', '1', 'Sier', 'Ra', 'Epitra' +), ( +'20' , 'Tango', '2134s65df423sdf132sdg401dsg', '1', 'Tan', 'Go', 'Epitra' +), ( +'21' , 'Uniform', '2134s65df423sdf132sdg401dsg', '1', 'Uni', 'Form', 'Epitra' +), ( +'22' , 'Victor', '2134s65df423sdf132sdg401dsg', '1', 'Vic', 'Tor', 'Epitra' +), ( +'23' , 'Whiskey', '2134s65df423sdf132sdg401dsg', '1', 'Whis', 'Key', 'Epitra' +), ( +'24' , 'X-ray', '2134s65df423sdf132sdg401dsg', '1', 'X', 'Rey', 'Epitra' +), ( +'25' , 'Yankee', '2134s65df423sdf132sdg401dsg', '1', 'Yan', 'Kee', 'Epitra' +), ( +'26' , 'Zulu', '2134s65df423sdf132sdg401dsg', '1', 'Zul', 'Lu', 'Epitra' +), ( +'27' , 'Zero', '2134s65df423sdf132sdg401dsg', '1', 'Ze', 'Ro', 'Epitra' +); + +INSERT INTO `fic`.`themes` ( `id` , `filename` ) @@ -20,187 +85,57 @@ VALUES ( '8' , 'pcap.xml' ); -INSERT INTO `fic2014`.`users` ( -`id` , -`username` , -`password` , -`auth_level` -) -VALUES ( -'1' , 'Alpha', UNHEX( '' ) , '1' -), ( -'2' , 'Bravo', UNHEX( '' ) , '1' -), ( -'3' , 'Charlie', UNHEX( '' ) , '1' -), ( -'4' , 'Delta', UNHEX( '' ) , '1' -), ( -'5' , 'Echo', UNHEX( '' ) , '1' -), ( -'6' , 'Foxtrot', UNHEX( '' ) , '1' -), ( -'7' , 'Golf', UNHEX( '' ) , '1' -), ( -'8' , 'Hotel', UNHEX( '' ) , '1' -), ( -'9' , 'India', UNHEX( '' ) , '1' -), ( -'10' , 'Juliet', UNHEX( '' ) , '1' -), ( -'11' , 'Kilo', UNHEX( '' ) , '1' -), ( -'12' , 'Lima', UNHEX( '' ) , '1' -), ( -'13' , 'Mike', UNHEX( '' ) , '1' -), ( -'14' , 'November', UNHEX( '' ) , '1' -), ( -'15' , 'Oscar', UNHEX( '' ) , '1' -), ( -'16' , 'Papa', UNHEX( '' ) , '1' -), ( -'17' , 'Quebec', UNHEX( '' ) , '1' -), ( -'18' , 'Romeo', UNHEX( '' ) , '1' -), ( -'19' , 'Sierra', UNHEX( '' ) , '1' -), ( -'20' , 'Tango', UNHEX( '' ) , '1' -), ( -'21' , 'Uniform', UNHEX( '' ) , '1' -), ( -'22' , 'Victor', UNHEX( '' ) , '1' -), ( -'23' , 'Whiskey', UNHEX( '' ) , '1' -), ( -'24' , 'X-ray', UNHEX( '' ) , '1' -), ( -'25' , 'Yankee', UNHEX( '' ) , '1' -), ( -'26' , 'Zulu', UNHEX( '' ) , '1' -), ( -'27' , 'Zero', UNHEX( '' ) , '1' -); - -INSERT INTO `fic2014`.`exercices` ( +INSERT INTO `fic`.`exercices` ( `id` , `id_theme` , -`points` +`require` , +`level` , +`points` , +`statement` ) VALUES -('1', '1', '1'), -('2', '1', '5'), -('3', '1', '10'), -('4', '1', '20'), -('5', '1', '40'), -('6', '2', '1'), -('7', '2', '5'), -('8', '2', '10'), -('9', '2', '20'), -('10', '2', '40'), -('11', '3', '1'), -('12', '3', '5'), -('13', '3', '10'), -('14', '3', '20'), -('15', '3', '40'), -('16', '4', '1'), -('17', '4', '5'), -('18', '4', '10'), -('19', '4', '20'), -('20', '4', '40'), -('21', '5', '1'), -('22', '5', '5'), -('23', '5', '10'), -('24', '5', '20'), -('25', '5', '40'), -('26', '6', '1'), -('27', '6', '5'), -('28', '6', '10'), -('29', '6', '20'), -('30', '6', '40'), -('31', '7', '1'), -('32', '7', '5'), -('33', '7', '10'), -('34', '7', '20'), -('35', '7', '40'), -('36', '8', '1'), -('37', '8', '5'), -('38', '8', '10'), -('39', '8', '20'), -('40', '8', '40'); +('1', '1', '', '1', '1', 'Description 1'), +('2', '1', '1', '2', '5', 'Description 2'), +('3', '1', '2', '3', '10', 'Description 3'), +('4', '1', '3', '4', '20', 'Description 4'), +('5', '1', '4', '5', '40', 'Description 5'), +('6', '2', '', '1', '1', 'Description 6'), +('7', '2', '6', '2', '5', 'Description 7'), +('8', '2', '7', '3', '10', 'Description 8'), +('9', '2', '8', '4', '20', 'Description 9'), +('10', '2', '9', '5', '40', 'Description 10'), +('11', '3', '', '1', '1', 'Description 11'), +('12', '3', '11', '2', '5', 'Description 12'), +('13', '3', '12', '3', '10', 'Description 13'), +('14', '3', '13', '4', '20', 'Description 14'), +('15', '3', '14', '5', '40', 'Description 15'), +('16', '4', '', '1', '1', 'Description 16'), +('17', '4', '16', '2', '5', 'Description 17'), +('18', '4', '17', '3', '10', 'Description 18'), +('19', '4', '18', '4', '20', 'Description 19'), +('20', '4', '19', '5', '40', 'Description 20'), +('21', '5', '', '1', '1', 'Description 21'), +('22', '5', '21', '2', '5', 'Description 22'), +('23', '5', '22', '3', '10', 'Description 23'), +('24', '5', '23', '4', '20', 'Description 24'), +('25', '5', '24', '5', '40', 'Description 25'), +('26', '6', '', '1', '1', 'Description 26'), +('27', '6', '26', '2', '5', 'Description 27'), +('28', '6', '27', '3', '10', 'Description 28'), +('29', '6', '28', '4', '20', 'Description 29'), +('30', '6', '29', '5', '40', 'Description 30'), +('31', '7', '', '1', '1', 'Description 31'), +('32', '7', '30', '2', '5', 'Description 32'), +('33', '7', '31', '3', '10', 'Description 33'), +('34', '7', '32', '4', '20', 'Description 34'), +('35', '7', '33', '5', '40', 'Description 35'), +('36', '8', '', '1', '1', 'Description 36'), +('37', '8', '35', '2', '5', 'Description 37'), +('38', '8', '36', '3', '10', 'Description 38'), +('39', '8', '37', '4', '20', 'Description 39'), +('40', '8', '38', '5', '40', 'Description 40'); -INSERT INTO `fic2014`.`exercice_dependancies` ( -`id` , -`id_exercice` , -`id_dependence` -) -VALUES ( -'1', '2', '1' -), ( -'2', '3', '2' -), ( -'3', '4', '3' -), ( -'4', '5', '4' -), ( -'5', '7', '6' -), ( -'6', '8', '7' -), ( -'7', '9', '8' -), ( -'8', '10', '9' -), ( -'9', '12', '11' -), ( -'10', '13', '12' -), ( -'11', '14', '13' -), ( -'12', '15', '14' -), ( -'13', '17', '16' -), ( -'14', '18', '17' -), ( -'15', '19', '18' -), ( -'16', '20', '19' -), ( -'17', '22', '21' -), ( -'18', '23', '22' -), ( -'19', '24', '23' -), ( -'20', '25', '24' -), ( -'21', '27', '26' -), ( -'22', '28', '27' -), ( -'23', '29', '28' -), ( -'24', '30', '29' -), ( -'25', '32', '31' -), ( -'26', '33', '32' -), ( -'27', '34', '33' -), ( -'28', '35', '34' -), ( -'29', '37', '36' -), ( -'30', '38', '37' -), ( -'31', '39', '38' -), ( -'32', '40', '39' -); - -INSERT INTO `fic2014`.`solved` ( +INSERT INTO `fic`.`solved` ( `id` , `id_user` , `id_exercice` , From a767c4d900b1d5366d29ed05b7b921990e68a5e1 Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Tue, 22 Oct 2013 08:56:38 +0200 Subject: [PATCH 0041/2518] Correct some bugs in Team class. --- onyx/include/common/Team.class.php | 34 +++++++++++++++++------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 8ad7e448..1bf78e85 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -2,6 +2,16 @@ if(!defined('ONYX')) exit; +function cmp_team_pts($i1, $i2) +{ + if ($i1->get_pts() == $i2->get_pts()){ + return 0; + } + else{ + return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; + } +} + class Team { var $id = null; @@ -24,6 +34,7 @@ class Team if (!empty($res)) { + $this->id = $res['id']; $this->firstname = $res['firstname']; $this->lastname = $res['lastname']; $this->username = $res['username']; @@ -94,15 +105,16 @@ class Team function get_pts() { - if(isset($this->points)) + if(!isset($this->points)) { $db = new BDD(); - $res = $db->query("SELECT e.id, s.id_user, SUM(e.points) as sum_points + $res = $db->unique_query("SELECT e.id, s.id_user, SUM(e.points) as sum_points FROM exercices e LEFT OUTER JOIN solved s ON e.id = s.id_exercice - WHERE s.id_user = " . intval($this->id) . " + WHERE s.id_user = " . $this->id . " GROUP BY s.id_user"); + $db->deconnexion(); if (!empty($res)) @@ -110,6 +122,8 @@ class Team $this->points = $res['sum_points']; } } + + return $this->points; } function get_groupIds() @@ -145,19 +159,9 @@ class Team // TODO: Not tested, need feeding BDD public static function get_top() { - function cmp($i1, $i2) - { - if ($i1->get_pts() == $i2->get_pts()){ - return 0; - } - else{ - return ($i1->get_pts() < $i2->get_pts) ? -1 : 1; - } - } - - $teams = $this->get_teams(); + $teams = Team::get_teams(); - usort($teams, "cmp"); + usort($teams, "cmp_team_pts"); return $teams; } From 9c3173c6823786183de31027c3c495df837ea1a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 23 Oct 2013 21:32:17 +0200 Subject: [PATCH 0042/2518] Fix User -> Team --- onyx/include/common/Team.class.php | 67 +++++++++++++++--------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 1bf78e85..4debbf23 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -15,13 +15,11 @@ function cmp_team_pts($i1, $i2) class Team { var $id = null; - var $firstname; - var $lastname; - var $username; - var $company; + var $key_hash; var $auth_level; + var $company; + var $members = null; var $points = null; - var $nb_themes = null; // Constructor function Team ($id=null) @@ -29,15 +27,13 @@ class Team if (!empty($id)) { $db = new BDD(); - $res = $db->unique_query("SELECT id, firstname, lastname, username, company, auth_level - FROM users WHERE id=" . intval($id)); + $res = $db->unique_query("SELECT id, key_hash, company, auth_level + FROM teams WHERE id=" . intval($id)) or die($db->erreur()); if (!empty($res)) { $this->id = $res['id']; - $this->firstname = $res['firstname']; - $this->lastname = $res['lastname']; - $this->username = $res['username']; + $this->key_hash = $res['key_hash']; $this->company = $res['company']; $this->auth_level = $res['auth_level']; } @@ -48,29 +44,25 @@ class Team // Class methods function update() { - $username = $this->username; + $key_hash = $this->key_hash; $auth_level = intval($this->auth_level); - $firstname = $this->firstname; - $lastname = $this->lastname; $company = $this->company; $db = new BDD(); - $db->escape($username); - $db->escape($firstname); - $db->escape($lastname); + $db->escape($key_hash); $db->escape($company); if (empty($this->id)) { - $db->query("INSERT INTO users - VALUES (NULL, '".$username."', 0x0, ".$auth_level.", '".$firstname."', '".$lastname."', '".$company."')"); + $db->query("INSERT INTO teams + VALUES (NULL, '".$key_hash."', ".$auth_level.", '".$company."')"); $this->id = $db->insert_id(); $aff = ($this->id > 0); } else { $db->query("UPDATE users - SET username = '".$username."', auth_level = '".$auth_level."', firstname = '".$firstname."', lastname = '".$lastname."', company = '".$company."' + SET auth_level = ".$auth_level.", key_hash = '".$key_hash."', company = '".$company."' WHERE id = ".intval($this->id)); $aff = $db->affected(); } @@ -83,18 +75,6 @@ class Team return $this->id; } - function get_firstname() { - return $this->firstname; - } - - function get_lastname() { - return $this->lastname; - } - - function get_username() { - return $this->username; - } - function get_company() { return $this->company; } @@ -103,6 +83,25 @@ class Team return $this->auth_level; } + function get_members() + { + if(!isset($this->members)) + { + $db = new BDD(); + + $res = $db->query("SELECT id, firstname, lastname, nickname + FROM team_members + WHERE id_team = " . intval($this->id)); + + $db->deconnexion(); + + if (!empty($res)) + $this->members = $res; + } + + return $this->members; + } + function get_pts() { if(!isset($this->points)) @@ -145,7 +144,7 @@ class Team public static function get_teams() { $db = new BDD(); - $ids = $db->query("SELECT `id` FROM `users`"); + $ids = $db->query("SELECT `id` FROM `teams`"); $db->deconnexion(); $array = array(); @@ -160,9 +159,9 @@ class Team public static function get_top() { $teams = Team::get_teams(); - + usort($teams, "cmp_team_pts"); return $teams; } -} \ No newline at end of file +} From 8a39c734fb11af87469355d333f9b7124613f055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 23 Oct 2013 21:36:06 +0200 Subject: [PATCH 0043/2518] New db schema --- db/fic2014.sql | 91 +++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/db/fic2014.sql b/db/fic2014.sql index 63dda3bd..0dfd2dd5 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -1,39 +1,39 @@ -- phpMyAdmin SQL Dump --- version 3.5.1 +-- version 4.0.5 -- http://www.phpmyadmin.net -- --- Client: localhost --- Généré le: Mer 09 Octobre 2013 à 23:52 --- Version du serveur: 5.5.32-log --- Version de PHP: 5.5.0-pl0-gentoo +-- Host: localhost +-- Generation Time: Oct 23, 2013 at 07:34 PM +-- Server version: 5.1.70-log +-- PHP Version: 5.5.4-pl0-gentoo -SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- --- Base de données: `fic2014` +-- Database: `fic2014` -- -- -------------------------------------------------------- -- --- Structure de la table `exercices` +-- Table structure for table `exercices` -- CREATE TABLE IF NOT EXISTS `exercices` ( - `id` varchar(100) COLLATE utf16_unicode_ci NOT NULL, + `id` varchar(100) COLLATE utf8_unicode_ci NOT NULL, `id_theme` int(10) unsigned NOT NULL, - `require` varchar(100) COLLATE utf16_unicode_ci NOT NULL, + `require` varchar(100) COLLATE utf8_unicode_ci NOT NULL, `level` tinyint(4) NOT NULL, `points` smallint(6) NOT NULL, - `statement` text COLLATE utf16_unicode_ci NOT NULL, + `statement` text COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- -------------------------------------------------------- -- --- Structure de la table `exercice_files` +-- Table structure for table `exercice_files` -- CREATE TABLE IF NOT EXISTS `exercice_files` ( @@ -48,7 +48,7 @@ CREATE TABLE IF NOT EXISTS `exercice_files` ( -- -------------------------------------------------------- -- --- Structure de la table `exercice_keys` +-- Table structure for table `exercice_keys` -- CREATE TABLE IF NOT EXISTS `exercice_keys` ( @@ -62,7 +62,7 @@ CREATE TABLE IF NOT EXISTS `exercice_keys` ( -- -------------------------------------------------------- -- --- Structure de la table `sessions` +-- Table structure for table `sessions` -- CREATE TABLE IF NOT EXISTS `sessions` ( @@ -79,7 +79,7 @@ CREATE TABLE IF NOT EXISTS `sessions` ( -- -------------------------------------------------------- -- --- Structure de la table `solved` +-- Table structure for table `solved` -- CREATE TABLE IF NOT EXISTS `solved` ( @@ -88,38 +88,45 @@ CREATE TABLE IF NOT EXISTS `solved` ( `id_exercice` int(10) unsigned NOT NULL, `time` datetime NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; -- -------------------------------------------------------- -- --- Structure de la table `themes` +-- Table structure for table `teams` +-- + +CREATE TABLE IF NOT EXISTS `teams` ( + `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `key_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `auth_level` tinyint(1) NOT NULL, + `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `team_members` +-- + +CREATE TABLE IF NOT EXISTS `team_members` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_team` int(10) unsigned NOT NULL, + `firstname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `lastname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `nickname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `themes` -- CREATE TABLE IF NOT EXISTS `themes` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `filename` varchar(255) COLLATE utf16_unicode_ci NOT NULL, + `filename` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - --- --- Structure de la table `users` --- - -CREATE TABLE IF NOT EXISTS `users` ( - `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, - `username` varchar(255) COLLATE utf16_unicode_ci NOT NULL, - `password` binary(64) NOT NULL, - `auth_level` tinyint(1) NOT NULL, - `firstname` varchar(255) COLLATE utf16_unicode_ci NOT NULL, - `lastname` varchar(255) COLLATE utf16_unicode_ci NOT NULL, - `company` varchar(255) COLLATE utf16_unicode_ci NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=2 ; - - -INSERT INTO users (username, password, auth_level) -VALUES -("nemunaire", UNHEX('c1d050d16d8c90dae6fef376460299aa8d1cce7c5b299720a8e38952a77212f1019e2cd44ba58e0433c01cb4c81ab9a789c07df218b0b9f05af8d1198a3bd239'), 2); +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; From 5abb9d8713d10f2f96da3eef5733f02114b92045 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 24 Oct 2013 17:40:12 +0200 Subject: [PATCH 0044/2518] Deleted login.php, login.tpl, login.css --- htdocs/css/login.css | 37 ----------------------------- onyx/include/public/login.php | 29 ---------------------- onyx/tpl/bootstrap/public/login.tpl | 18 -------------- 3 files changed, 84 deletions(-) delete mode 100644 htdocs/css/login.css delete mode 100644 onyx/include/public/login.php delete mode 100644 onyx/tpl/bootstrap/public/login.tpl diff --git a/htdocs/css/login.css b/htdocs/css/login.css deleted file mode 100644 index f7bf2623..00000000 --- a/htdocs/css/login.css +++ /dev/null @@ -1,37 +0,0 @@ -body { - padding-top: 40px; - background-color: #eee; -} - -.form-signin { - max-width: 330px; - padding: 15px; - margin: 0 auto; -} -.form-signin .form-signin-heading, - -.form-signin .checkbox { - font-weight: normal; -} -.form-signin .form-control { - position: relative; - font-size: 16px; - height: auto; - padding: 10px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.form-signin .form-control:focus { - z-index: 2; -} -.form-signin input[type="text"] { - margin-bottom: -1px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.form-signin input[type="password"] { - margin-bottom: 10px; - border-top-left-radius: 0; - border-top-right-radius: 0; -} diff --git a/onyx/include/public/login.php b/onyx/include/public/login.php deleted file mode 100644 index 1b22cbac..00000000 --- a/onyx/include/public/login.php +++ /dev/null @@ -1,29 +0,0 @@ -escape($username); - $bdd->escape($password); - $hash = mdp($username, $password); - $result = $bdd->unique_query("SELECT id, username, auth_level FROM users - WHERE username='$username' - AND password=unhex('$hash')"); - - if (!empty($result) && $result['auth_level'] != 0) - { - $SESS->level = $result["auth_level"]; - $SESS->values = $result; - $SESS->put($result["id"]); - header("Location: /home"); - exit; - } -} - -$page = "public/login"; diff --git a/onyx/tpl/bootstrap/public/login.tpl b/onyx/tpl/bootstrap/public/login.tpl deleted file mode 100644 index 59a794ee..00000000 --- a/onyx/tpl/bootstrap/public/login.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{extends file="layout-nav.tpl"} - -{block name=head} - -{/block} - -{block name=content} - -
- -
- -{/block} From 026660aa2ffb4a6581565457278c7a05bfb77c8d Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sat, 26 Oct 2013 02:49:38 +0200 Subject: [PATCH 0045/2518] Add script for certs --- misc/certs/CA.sh | 49 ++++++ misc/certs/openssl.cnf | 352 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 401 insertions(+) create mode 100755 misc/certs/CA.sh create mode 100644 misc/certs/openssl.cnf diff --git a/misc/certs/CA.sh b/misc/certs/CA.sh new file mode 100755 index 00000000..f8378fc1 --- /dev/null +++ b/misc/certs/CA.sh @@ -0,0 +1,49 @@ +# Create CA for client +#openssl genrsa -des3 -out ca.key 4096 +#openssl req -new -x509 -days 365 -key ca.key -out ca.crt +# +## Server cert +#openssl genrsa -des3 -out server.key 2028 +#openssl req -new -key server.key -out server.csr +# +## Self sign ?? +#openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt + +# TODO serial +# TODO common name + +OPENSSL_CONF=openssl.cnf + +[ $# -ne 1 ] && echo "Usage: $0 init + client NAME" + +case $1 in + "init" ) + echo "Create CA for signing client certs" + openssl genrsa -des3 -out ca.key 4096 + sed -i 's/=.*#CommonName/= FIC2014 CA#CommonNameEnd/' $OPENSSL_CONF + openssl req -batch -new -x509 -days 365 -key ca.key -out ca.crt + + echo "Create server cert" + openssl genrsa -des3 -out server.key 2048 + sed -i 's/=.*#CommonNameEnd/= FIC2014 Server#CommonNameEnd/' $OPENSSL_CONF + openssl req -batch -new -key server.key -out server.csr + openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt + rm server.csr + ;; + "client" ) + [ $# -ne 2 ] && "client Usage" + openssl genrsa -des3 -out client.key 2048 + sed -i "s/=.*#CommonNameEnd/= $2#CommonNameEnd/" $OPENSSL_CONF + openssl req -batch -new -key client.key -out client.csr + openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt + openssl pkcs12 -export -inkey client.key -in client.crt -name $2 -out ${2}.p12 + + rm client.key + rm client.csr + rm client.crt + ;; + "*" ) + echo "*" + ;; +esac diff --git a/misc/certs/openssl.cnf b/misc/certs/openssl.cnf new file mode 100644 index 00000000..d7afe95d --- /dev/null +++ b/misc/certs/openssl.cnf @@ -0,0 +1,352 @@ +# +# OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = /etc/ssl # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several ctificates with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = FR +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = France + +localityName = Locality Name (eg, city) +localityName_default = Paris + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Epita + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = SRS + +commonName = Common Name (e.g. server FQDN or YOUR name) +commonName_default = tata#CommonNameEndEndEndEndEnd +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1 # the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir = ./demoCA # TSA root directory +serial = $dir/tsaserial # The current serial number (mandatory) +crypto_device = builtin # OpenSSL engine to use for signing +signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) +certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) +signer_key = $dir/private/tsakey.pem # The TSA private key (optional) + +default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) +other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +digests = md5, sha1 # Acceptable message digests (mandatory) +accuracy = secs:1, millisecs:500, microsecs:100 # (optional) +clock_precision_digits = 0 # number of digits after dot. (optional) +ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) +tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) +ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) From 30135b4c6e1617e64b27141e56c5beafd649e2fb Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sat, 26 Oct 2013 02:49:59 +0200 Subject: [PATCH 0046/2518] Add install script --- misc/init_db.sql | 2 ++ misc/install.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ misc/server.conf | 5 ++++ 3 files changed, 75 insertions(+) create mode 100644 misc/init_db.sql create mode 100755 misc/install.sh create mode 100644 misc/server.conf diff --git a/misc/init_db.sql b/misc/init_db.sql new file mode 100644 index 00000000..e2ca05e8 --- /dev/null +++ b/misc/init_db.sql @@ -0,0 +1,2 @@ +DROP DATABASE IF EXISTS fic2014; +CREATE DATABASE fic2014; diff --git a/misc/install.sh b/misc/install.sh new file mode 100755 index 00000000..ede53942 --- /dev/null +++ b/misc/install.sh @@ -0,0 +1,68 @@ +#! /bin/sh + +# Install FIC 2014 server + +# Depends: +# +# nginx 1.4.3 +# openssh 6.3p1-1 +# iptables 1.4.19.1-1 +# mariadb 5.5.33.a-1 + +# Exit values +# 0 Everything is good +# 1 +# 2 File not found +# 3 Service not running + +# By default the config dir is .. +DIR=${PWD%/*} +CONF="server.conf" +BASENAME=`basename $0` +FULL_INSTALL=false + +display_help() +{ + # By default install only config files + # --full: install package, enable services, install config + echo "Usage: $BASENAME [--full] (alpha|beta)" + exit 1 +} + +HTTP_DIR="" +DB_TYPE="" +DB_NAME="" +DB_USER="" +DB_PASS="" + +parse_conf() +{ + if ! [ -f $CONF ]; then + echo "The configuration file: " $CONF " not found" + exit 2 + fi + HTTP_DIR=$(sed -n 's/[ \t]*http_root[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) + DB_TYPE=$(sed -n 's/[ \t]*db_type[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) + DB_NAME=$(sed -n 's/[ \t]*db_name[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) + DB_USER=$(sed -n 's/[ \t]*db_user[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) + DB_PASS=$(sed -n 's/[ \t]*db_pass[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) +} + +INIT_DB="init_db.sql" + +init_db() +{ + if ! [ -f $INIT_DB ]; then + echo "The configuration file " $INIT_DB " not found" + exit 2 + fi + + if ! [ -S /var/run/mysqld/mysqld.sock ]; then + echo "The mysqld service is not running" + exit 3 + fi +} + +[ $# -ne 1 ] && display_help + +parse_conf diff --git a/misc/server.conf b/misc/server.conf new file mode 100644 index 00000000..c9ec3d86 --- /dev/null +++ b/misc/server.conf @@ -0,0 +1,5 @@ +http_root=/srv/http/fic2014-server +db_type=mysql +db_name=fic +db_user=toto +db_pass=toto42 From 7571c8c1b12655650dc1edae3271a381ec9b50b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 08:56:06 +0200 Subject: [PATCH 0047/2518] Move directory tpl users to teams --- onyx/include/team/exercice.php | 2 +- onyx/include/team/home.php | 2 +- onyx/include/team/{change.php => me.php} | 2 +- onyx/include/team/summary.php | 2 +- onyx/include/team/team.php | 2 +- onyx/tpl/bootstrap/{users => teams}/home.tpl | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename onyx/include/team/{change.php => me.php} (61%) rename onyx/tpl/bootstrap/{users => teams}/home.tpl (100%) diff --git a/onyx/include/team/exercice.php b/onyx/include/team/exercice.php index d8ace4ea..84856f02 100644 --- a/onyx/include/team/exercice.php +++ b/onyx/include/team/exercice.php @@ -3,4 +3,4 @@ if(!defined('ONYX')) exit; -return "team/exercice"; +return "teams/exercice"; diff --git a/onyx/include/team/home.php b/onyx/include/team/home.php index 7521d39f..eaa60a72 100644 --- a/onyx/include/team/home.php +++ b/onyx/include/team/home.php @@ -5,4 +5,4 @@ if(!defined('ONYX')) exit; $template->assign("teams", Team::get_teams()); $template->assign("top", Team::get_top()); -return "users/home"; +return "teams/home"; diff --git a/onyx/include/team/change.php b/onyx/include/team/me.php similarity index 61% rename from onyx/include/team/change.php rename to onyx/include/team/me.php index 8a234331..bf209f06 100644 --- a/onyx/include/team/change.php +++ b/onyx/include/team/me.php @@ -3,4 +3,4 @@ if(!defined('ONYX')) exit; -return "team/change"; +return "teams/change"; diff --git a/onyx/include/team/summary.php b/onyx/include/team/summary.php index 3ab8aeca..62a22790 100644 --- a/onyx/include/team/summary.php +++ b/onyx/include/team/summary.php @@ -3,4 +3,4 @@ if(!defined('ONYX')) exit; -return "team/summary"; +return "teams/summary"; diff --git a/onyx/include/team/team.php b/onyx/include/team/team.php index dcc68e71..98333fdc 100644 --- a/onyx/include/team/team.php +++ b/onyx/include/team/team.php @@ -8,7 +8,7 @@ try $template->assign("team", $team); - return "team/team"; + return "teams/team"; } catch($e) { diff --git a/onyx/tpl/bootstrap/users/home.tpl b/onyx/tpl/bootstrap/teams/home.tpl similarity index 100% rename from onyx/tpl/bootstrap/users/home.tpl rename to onyx/tpl/bootstrap/teams/home.tpl From f8eff22c225c88dc88f24198c002d404fc275b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 08:59:59 +0200 Subject: [PATCH 0048/2518] Public part: home and team part --- htdocs/index.php | 12 +++++++----- onyx/include/public/team.php | 2 +- onyx/tpl/bootstrap/public/home.tpl | 5 +++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 57e1f8f3..50a4aeb4 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -12,6 +12,9 @@ if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "fic" | //Chargement de tout le nécessaire pour le site require_once("common.php"); +$template->assign("SALT_USER",SALT_USER); +$template->assign("SALT_ADMIN",SALT_ADMIN); + $n = preg_match_all("#[^/]+#", strtolower(gpc("p")), $out); $p = $out[0]; @@ -46,7 +49,6 @@ if ($n && $p[0] == SALT_ADMIN) else if ($n && $p[0] == SALT_USER) { $connected = true; - if ($n <= 1) $page = require("team/home.php"); else @@ -59,9 +61,9 @@ else if ($n && $p[0] == SALT_USER) { switch($p[2]) { - case "change/": - case "change": - $page = require("team/change.php"); + case "me/": + case "me": + $page = require("team/me.php"); break; case "summary": @@ -92,7 +94,7 @@ else $page = require("public/home.php"); else if ($n == 1) { - $TEAM = $p[0]; + $TEAM = intval(substr($p[0], 0, strpos($p[0], "-"))); $page = require("public/team.php"); } diff --git a/onyx/include/public/team.php b/onyx/include/public/team.php index dfd91661..71ccb620 100644 --- a/onyx/include/public/team.php +++ b/onyx/include/public/team.php @@ -10,7 +10,7 @@ try return "public/team"; } -catch($e) +catch(Exception $e) { return "404"; } diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 68369382..fb80872d 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -3,4 +3,9 @@

Hello World!

+{foreach from=$teams item=i} + +{/foreach} {/block} From 867d1d6f74944dc42598af49fe56956cf5dc4a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 09:00:21 +0200 Subject: [PATCH 0049/2518] Connected: fix top bar menu --- onyx/tpl/bootstrap/layout-nav.tpl | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/onyx/tpl/bootstrap/layout-nav.tpl b/onyx/tpl/bootstrap/layout-nav.tpl index 15f488ba..446e46f3 100644 --- a/onyx/tpl/bootstrap/layout-nav.tpl +++ b/onyx/tpl/bootstrap/layout-nav.tpl @@ -9,21 +9,13 @@ - FIC + FIC
From 73e1e8f127d0173c55f63d618ba5e0efc6add04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 09:04:22 +0200 Subject: [PATCH 0050/2518] DB: theme require a name, not filename --- db/fic2014.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/fic2014.sql b/db/fic2014.sql index 0dfd2dd5..ec666486 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -127,6 +127,6 @@ CREATE TABLE IF NOT EXISTS `team_members` ( CREATE TABLE IF NOT EXISTS `themes` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `filename` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; From c27a97ce6e1e0bcd5e513706df9a97c9ff004262 Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Sat, 26 Oct 2013 15:38:43 +0200 Subject: [PATCH 0051/2518] BDD: add 'teamname' and change feedfortest.sql --- db/feedfortests.sql | 103 ++++++++++++++++++++++++++++++-------------- db/fic2014.sql | 1 + 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/db/feedfortests.sql b/db/feedfortests.sql index 36fbafe2..b370d694 100644 --- a/db/feedfortests.sql +++ b/db/feedfortests.sql @@ -1,71 +1,108 @@ -INSERT INTO `fic`.`users` ( +INSERT INTO `fic`.`teams` ( `id` , -`username` , -`password` , +`team_name` , +`key_hash` , `auth_level` , -`firstname` , -`lastname` , `company` ) VALUES ( -'1', 'Alpha', '2134s65df423sdf132sdg431dsg', '1', 'Alph', 'A', 'Epitra' +'1', 'Team1', '2134s65df423sdf132sdg431dsg', '1', 'Epita' ), ( -'2', 'Beta', '2134s65df423sef132sdg431dsg', '1', 'Bet', 'A', 'Epitra' +'2', 'Team2', '2134s65df423sef132sdg431dsg', '1', 'Epita' ), ( -'3', 'Charli', '2134s45df423sdf132sdg431dsg', '1', 'Charl', 'I', 'Epitra' +'3', 'Team3', '2134s45df423sdf132sdg431dsg', '1', 'Epita' ), ( -'4', 'Delta', '2134s65df423sdf131sdg431dsg', '1', 'Delt', 'A', 'Epitra' +'4', 'Team4', '2134s65df423sdf131sdg431dsg', '1', 'Epita' ), ( -'5', 'Echo', '2134s65df423sdf132sdg431dfg', '1', 'Ech', 'O', 'Epitra' +'5', 'Team5', '2134s65df423sdf132sdg431dfg', '1', 'Epita' ), ( -'6', 'Foxtrot', '2134s65df423shf132sdg431dsg', '1', 'Fox', 'Trot', 'Epitra' +'6', 'Team6', '2134s65df423shf132sdg431dsg', '1', 'Epita' ), ( -'7', 'Golf', '2134s65df423sdf1f2sdg431dsg', '1', 'Gol', 'F', 'Epitra' +'7', 'Team7', '2134s65df423sdf1f2sdg431dsg', '1', 'Epita' ), ( -'8', 'Hotel', '2134s65df423sdf13zsdg431dsg', '1', 'Hot', 'El', 'Epitra' +'8', 'Team8', '2134s65df423sdf13zsdg431dsg', '1', 'Epita' ), ( -'9', 'India', '2134s65df423sdf13csdg431dsg', '1', 'Ind', 'Ia', 'Epitra' +'9', 'Team9', '2134s65df423sdf13csdg431dsg', '1', 'Epita' ), ( -'10', 'Juliet', '2134s65df4q3sdf132sdg431dsg', '1', 'Jule', 'Yer', 'Epitra' +'10', 'Team10', '2134s65df4q3sdf132sdg431dsg', '1', 'Epita' ), ( -'11', 'Kevlar', '2134s65df423sdf132s2g431dsg', '1', 'Krev', 'Lard', 'Epitra' +'11', 'Team11', '2134s65df423sdf132s2g431dsg', '1', 'Epita' ), ( -'12', 'Lambda', '2134s65df423sdf132sdg401dsg', '1', 'Lamb', 'Ada', 'Epitra' +'12', 'Team12', '2134s65df423sdf132sdg401dsg', '1', 'Epita' ), ( -'13' , 'Mike', '2134s65df423sdf132sdg401dsg', '1', 'Mi', 'Ke', 'Epitra' +'13' , 'Team13', '2134s65df423sdf132sdg401dsg', '1', 'Epita' ), ( -'14' , 'November', '2134s65df423sdf132sdg401dsg', '1', 'Nov', 'Ember', 'Epitra' +'14' , 'Team14', '2134s65df423sdf132sdg401dsg', '1', 'Epita' ), ( -'15' , 'Oscar', '2134s65df423sdf132sdg401dsg', '1', 'Os', 'Car', 'Epitra' +'15' , 'Team15', '2134s65df423sdf132sdg401dsg', '1', 'Epita' +); + +INSERT INTO `fic`.`team_members` ( +`id` , +`id_team` , +`firstname` , +`lastname` , +`nickname` +) +VALUES ( +'1', '1', 'Alph', 'A', 'Alominia' ), ( -'16' , 'Papa', '2134s65df423sdf132sdg401dsg', '1', 'Pa', 'Pa', 'Epitra' +'2', '1', 'Bet', 'A', 'CaptainSandwich' ), ( -'17' , 'Quebec', '2134s65df423sdf132sdg401dsg', '1', 'Que', 'Bec', 'Epitra' +'3', '2', 'Charl', 'I', 'Tintin' ), ( -'18' , 'Romeo', '2134s65df423sdf132sdg401dsg', '1', 'Rom', 'Eo', 'Epitra' +'4', '2', 'Delt', 'A', 'Wolwerin' ), ( -'19' , 'Sierra', '2134s65df423sdf132sdg401dsg', '1', 'Sier', 'Ra', 'Epitra' +'5', '3', 'Ech', 'O', 'Homer' ), ( -'20' , 'Tango', '2134s65df423sdf132sdg401dsg', '1', 'Tan', 'Go', 'Epitra' +'6', '3', 'Fox', 'Trot', 'KevBG91' ), ( -'21' , 'Uniform', '2134s65df423sdf132sdg401dsg', '1', 'Uni', 'Form', 'Epitra' +'7', '4', 'Gol', 'F', 'R2D2' ), ( -'22' , 'Victor', '2134s65df423sdf132sdg401dsg', '1', 'Vic', 'Tor', 'Epitra' +'8', '4', 'Hot', 'El', 'Corbaine' ), ( -'23' , 'Whiskey', '2134s65df423sdf132sdg401dsg', '1', 'Whis', 'Key', 'Epitra' +'9', '5', 'Ind', 'Ia', 'Lelama' ), ( -'24' , 'X-ray', '2134s65df423sdf132sdg401dsg', '1', 'X', 'Rey', 'Epitra' +'10', '5', 'Jule', 'Yer', 'Betrave' ), ( -'25' , 'Yankee', '2134s65df423sdf132sdg401dsg', '1', 'Yan', 'Kee', 'Epitra' +'11', '6', 'Krev', 'Lard', 'BlueSunday' ), ( -'26' , 'Zulu', '2134s65df423sdf132sdg401dsg', '1', 'Zul', 'Lu', 'Epitra' +'12', '6', 'Lamb', 'Ada', 'Chatpitre' ), ( -'27' , 'Zero', '2134s65df423sdf132sdg401dsg', '1', 'Ze', 'Ro', 'Epitra' +'13' , '7', 'Mi', 'Ke', 'Tournewsol' +), ( +'14' , '7', 'Nov', 'Ember', 'Dasilva' +), ( +'15' , '8', 'Os', 'Car', 'Laurie' +), ( +'16' , '8', 'Pa', 'Pa', 'Nowel' +), ( +'17' , '9', 'Que', 'Bec', 'Polyr' +), ( +'18' , '9', 'Rom', 'Eo', 'Granola' +), ( +'19' , '10', 'Sier', 'Ra', 'Petilus75' +), ( +'20' , '11', 'Tan', 'Go', 'Lolilol42' +), ( +'21' , '12', 'Uni', 'Form', 'JmLayfrite' +), ( +'22' , '13', 'Vic', 'Tor', 'Minerva' +), ( +'23' , '13', 'Whis', 'Key', 'Moly' +), ( +'24' , '14', 'X', 'Rey', 'Mistigri' +), ( +'25' , '14', 'Yan', 'Kee', 'Astroboy' +), ( +'26' , '15', 'Zul', 'Lu', 'Salameche' +), ( +'27' , '15', 'Ze', 'Ro', 'Mandy' ); INSERT INTO `fic`.`themes` ( `id` , -`filename` +`name` ) VALUES ( '1' , 'pdf.xml' diff --git a/db/fic2014.sql b/db/fic2014.sql index ec666486..1a5405ec 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -98,6 +98,7 @@ CREATE TABLE IF NOT EXISTS `solved` ( CREATE TABLE IF NOT EXISTS `teams` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `team_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `key_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `auth_level` tinyint(1) NOT NULL, `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL, From 30a7f656165c15a6228824f79ce1454649084070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 17:42:18 +0200 Subject: [PATCH 0052/2518] Add missing team.tpl page --- onyx/tpl/bootstrap/public/team.tpl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 onyx/tpl/bootstrap/public/team.tpl diff --git a/onyx/tpl/bootstrap/public/team.tpl b/onyx/tpl/bootstrap/public/team.tpl new file mode 100644 index 00000000..f9a9f87f --- /dev/null +++ b/onyx/tpl/bootstrap/public/team.tpl @@ -0,0 +1,16 @@ +{extends file="layout.tpl"} +{block name=content} +

+ {$team->company} +

+
    +
  • Score : {$team->get_pts()}
  • +
  • Membre{if count($team->get_members()) > 1}s{/if} : +
      + {foreach from=$team->get_members() item=m} +
    • {$m.lastname} {$m.firstname}
    • + {/foreach} +
    +
  • +
+{/block} From b069d8f4ed8280f3bf95417a59e64318a360650f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 18:17:25 +0200 Subject: [PATCH 0053/2518] New class Member, use it in Team ; update DB schema --- db/fic2014.sql | 11 ++-- onyx/include/common.php | 1 + onyx/include/common/Member.class.php | 84 ++++++++++++++++++++++++++++ onyx/include/common/Team.class.php | 35 ++++++------ onyx/tpl/bootstrap/public/team.tpl | 4 +- 5 files changed, 110 insertions(+), 25 deletions(-) create mode 100644 onyx/include/common/Member.class.php diff --git a/db/fic2014.sql b/db/fic2014.sql index ec666486..01945b2e 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -100,7 +100,7 @@ CREATE TABLE IF NOT EXISTS `teams` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `key_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `auth_level` tinyint(1) NOT NULL, - `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `slogan` varchar(64) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; @@ -113,9 +113,10 @@ CREATE TABLE IF NOT EXISTS `teams` ( CREATE TABLE IF NOT EXISTS `team_members` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id_team` int(10) unsigned NOT NULL, - `firstname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, - `lastname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, - `nickname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `firstname` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `lastname` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `nickname` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `company` varchar(32) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; @@ -127,6 +128,6 @@ CREATE TABLE IF NOT EXISTS `team_members` ( CREATE TABLE IF NOT EXISTS `themes` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `name` varchar(32) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; diff --git a/onyx/include/common.php b/onyx/include/common.php index 6754e327..6e0f0067 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -7,6 +7,7 @@ if (empty($sess->values["connected"]) && !defined("xCSRF")) require_once("functions.php"); //Inclusion des principales fonctions require_once("common/Exercice.class.php"); +require_once("common/Member.class.php"); require_once("common/Team.class.php"); require_once("common/Theme.class.php"); diff --git a/onyx/include/common/Member.class.php b/onyx/include/common/Member.class.php new file mode 100644 index 00000000..677b9c37 --- /dev/null +++ b/onyx/include/common/Member.class.php @@ -0,0 +1,84 @@ +unique_query("SELECT id, id_team, firstname, lastname, nickname, company + FROM team_members WHERE id=" . intval($id)) or die($db->erreur()); + $db->deconnexion(); + + if (!empty($res)) + { + $this->id = $res['id']; + if (empty($team)) + $this->team = $res['id_team']; + else + $this->team = $team; + $this->firstname = $res['firstname']; + $this->lastname = $res['lastname']; + $this->nickname = $res['nickname']; + $this->company = $res['company']; + } + } + } + + function update() + { + $firstname = $this->firstname; + $lastname = $this->lastname; + $nickname = $this->nickname; + $company = $this->company; + + if (gettype($this->team) != "object") + $id_team = intval($this->team); + else + $id_team = $this->team->id; + + $db = new BDD(); + $db->escape($firstname); + $db->escape($lastname); + $db->escape($nickname); + $db->escape($company); + + if (empty($this->id)) + { + $db->query("INSERT INTO team_members + VALUES (NULL, ".intval($id_team).", '".$firstname."', '".$lastname."', '".$nickname."', '".$company."')"); + $this->id = $db->insert_id(); + $aff = ($this->id > 0); + } + else + { + $db->query("UPDATE team_members + SET id_team = ".intval($id_team).", firstname = '$firstname', lastname = '$lastname', nickname = '$lastname', company = '$company' + WHERE id = ".intval($this->id)); + $aff = $db->affected(); + } + $db->deconnexion(); + + return ($aff == 1); + } + + function get_team() + { + if (gettype($this->team) != "object") + $this->team = new Team(intval($this->team)); + + return $this->team; + } +} + +?> \ No newline at end of file diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 4debbf23..aeeb6799 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -17,8 +17,8 @@ class Team var $id = null; var $key_hash; var $auth_level; - var $company; - var $members = null; + var $slogan; + var $members = array(); var $points = null; // Constructor @@ -27,14 +27,14 @@ class Team if (!empty($id)) { $db = new BDD(); - $res = $db->unique_query("SELECT id, key_hash, company, auth_level + $res = $db->unique_query("SELECT id, key_hash, slogan, auth_level FROM teams WHERE id=" . intval($id)) or die($db->erreur()); if (!empty($res)) { $this->id = $res['id']; $this->key_hash = $res['key_hash']; - $this->company = $res['company']; + $this->slogan = $res['slogan']; $this->auth_level = $res['auth_level']; } $db->deconnexion(); @@ -46,23 +46,23 @@ class Team { $key_hash = $this->key_hash; $auth_level = intval($this->auth_level); - $company = $this->company; + $slogan = $this->slogan; $db = new BDD(); $db->escape($key_hash); - $db->escape($company); + $db->escape($slogan); if (empty($this->id)) { $db->query("INSERT INTO teams - VALUES (NULL, '".$key_hash."', ".$auth_level.", '".$company."')"); + VALUES (NULL, '".$key_hash."', ".$auth_level.", '".$slogan."')"); $this->id = $db->insert_id(); $aff = ($this->id > 0); } else { - $db->query("UPDATE users - SET auth_level = ".$auth_level.", key_hash = '".$key_hash."', company = '".$company."' + $db->query("UPDATE teams + SET auth_level = ".$auth_level.", key_hash = '".$key_hash."', slogan = '".$slogan."' WHERE id = ".intval($this->id)); $aff = $db->affected(); } @@ -75,8 +75,8 @@ class Team return $this->id; } - function get_company() { - return $this->company; + function get_slogan() { + return $this->slogan; } function get_auth_level() { @@ -85,18 +85,17 @@ class Team function get_members() { - if(!isset($this->members)) + if(count($this->members) == 0) { $db = new BDD(); - $res = $db->query("SELECT id, firstname, lastname, nickname - FROM team_members + $res = $db->query("SELECT id FROM team_members WHERE id_team = " . intval($this->id)); $db->deconnexion(); - if (!empty($res)) - $this->members = $res; + foreach($res as $member) + $this->members[] = new Member($member["id"], $this); } return $this->members; @@ -117,9 +116,9 @@ class Team $db->deconnexion(); if (!empty($res)) - { $this->points = $res['sum_points']; - } + else + $this->points = 0; } return $this->points; diff --git a/onyx/tpl/bootstrap/public/team.tpl b/onyx/tpl/bootstrap/public/team.tpl index f9a9f87f..39094e42 100644 --- a/onyx/tpl/bootstrap/public/team.tpl +++ b/onyx/tpl/bootstrap/public/team.tpl @@ -1,14 +1,14 @@ {extends file="layout.tpl"} {block name=content}

- {$team->company} + {$team->slogan}

- -
+ +
From fd855c0f0d43063f2600e878d9f3350f166eed6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Mon, 25 Nov 2013 15:38:42 +0100 Subject: [PATCH 0108/2518] Add clock.tpl --- onyx/tpl/bootstrap/clock.tpl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 onyx/tpl/bootstrap/clock.tpl diff --git a/onyx/tpl/bootstrap/clock.tpl b/onyx/tpl/bootstrap/clock.tpl new file mode 100644 index 00000000..05c184c2 --- /dev/null +++ b/onyx/tpl/bootstrap/clock.tpl @@ -0,0 +1,20 @@ +
+ + +
+
    +
  • +
  • :
  • +
  • +
  • :
  • +
  • +
+
From c5f96c8bb99db867fe6b2ae5f2fabc2c652fb479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Mon, 25 Nov 2013 15:55:12 +0100 Subject: [PATCH 0109/2518] Ignore submissions --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 571d5f74..cb02566c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ onyx/log/* onyx/config/root.xml onyx/db/*.profile.php onyx/tpl/*/*.html +submission/* From e137e755c07ce7947f74bef171c8d079dbd417e2 Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Mon, 25 Nov 2013 21:12:01 +0100 Subject: [PATCH 0110/2518] Add public array --- onyx/include/common/Team.class.php | 17 +++++++++++++ onyx/tpl/bootstrap/public/home.tpl | 40 ++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 7494898a..3a2cd470 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -232,4 +232,21 @@ class Team return $res['count_teams']; } + + public static function first_to_solve_exercice($id_exercice) + { + $db = new BDD(); + $res = $db->unique_query("SELECT t3.team_name as result + FROM solved AS t1 + INNER JOIN ( + SELECT MIN(s.time) AS minTime + FROM solved AS s + WHERE s.id_exercice = ".$id_exercice." + ) AS t2 + INNER JOIN teams AS t3 ON t1.id_team = t3.id + WHERE t1.time = t2.minTime"); + $db->deconnexion(); + + return $res['result']; + } } diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 2fe5783b..6f0d757e 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -2,12 +2,38 @@ {block name=main}
-

Example

-

This is a example

-

This is a example

-

This is a example

-

This is a example

-

This is a example

-

This is a example

+ + + + + +{for $i=1 to $nbExoMax} + +{/for} + + + +{$total=0} +{foreach from=$themes item=theme} + + + {$themeID=$theme->get_id()} + {foreach from=$theme->get_exercices_ordered() item=exo} + {$teamName=""} + {for $i=0 to $nbExoMax} + {$teamName=Team::first_to_solve_exercice($exo->get_id())} + {/for} + {if $teamName != ""} + + {else} + + {/if} + {/foreach} + +{/foreach} + +
Exercice {$i}
{$theme->get_name()}{$teamName}
+ +
{/block} From a9fdcaf9f260b8634bc7c808725d10dee75ef23d Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 18:24:46 +0100 Subject: [PATCH 0111/2518] Use a variable to handle the misc_dir --- onyx/include/admin/certificate.php | 46 +++++++++++++++++++---------- onyx/include/admin/home.php | 27 ++++++++++++----- onyx/include/admin/import_users.php | 11 +++++-- 3 files changed, 58 insertions(+), 26 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index ce7b4016..89e9ca61 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -24,39 +24,53 @@ function remove_directory($dir) function new_client($name) { - //TODO handle if already exist - putenv("OPENSSL_CONF=".ONYX. '../misc/openssl.cnf'); - putenv("TOP_DIR=".ONYX. '../misc/pki'); - $output = shell_exec(ONYX . "../misc/CA.sh -newclient $name"); + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return "admin/home"; + } + + //TODO handle if already exist + putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); + putenv("TOP_DIR=$misc_dir/pki"); + $output = shell_exec("$misc_dir/CA.sh -newclient $name"); } if (!empty($p[2])) { + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return "admin/home"; + } + + $misc_dir = $VAR['misc_dir']; + if ($p[2] == "newca") { - //TODO handle if already exist - putenv("OPENSSL_CONF=".ONYX. '../misc/openssl.cnf'); - putenv("TOP_DIR=".ONYX. '../misc/pki'); - $output = shell_exec(ONYX . '../misc/CA.sh -newca'); + putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); + putenv("TOP_DIR=$misc_dir/pki"); + $output = shell_exec("$misc_dir/CA.sh -newca"); - //TODO handle the path ? - $ca_file = ONYX . '../misc/pki/cacert.crt'; + $ca_file = "$misc_dir/pki/cacert.crt"; //TODO check permission ? if (file_exists($ca_file)) { - $data = openssl_x509_parse(file_get_contents(ONYX . '../misc/pki/cacert.crt')); + $data = openssl_x509_parse(file_get_contents("$misc_dir/pki/cacert.crt")); $template->assign("cert", $data); } } elseif ($p[2] == "deleteca") { - //TODO handle var path - $dir = ONYX . '../misc/pki'; - + $dir = "$misc_dir/pki"; remove_directory($dir); } } -//header("Location: /admin/"); -//exit; \ No newline at end of file +header("Location: /admin/"); +exit; diff --git a/onyx/include/admin/home.php b/onyx/include/admin/home.php index 2e333fa1..79bcbfcc 100644 --- a/onyx/include/admin/home.php +++ b/onyx/include/admin/home.php @@ -2,20 +2,31 @@ if(!defined('ONYX')) exit; -if (is_writable(ONYX."../misc/") && !is_dir(ONYX."../misc/pki/")) - mkdir(ONYX."../misc/pki/"); +if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; +else +{ + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return "admin/home"; +} -$wright = is_writable(ONYX."../misc/pki/"); +if (is_writable($misc_dir) && !is_dir("$misc_dir/pki/")) + mkdir("$misc_dir/pki/"); + +$wright = is_writable("$misc_dir/pki/"); $template->assign("cert_writable", $wright); -//TODO handle the path ? -$ca_file = ONYX . '../misc/pki/cacert.crt'; +$ca_file = "$misc_dir/pki/cacert.crt"; -//TODO check permission ? if (file_exists($ca_file)) { - $data = openssl_x509_parse(file_get_contents(ONYX . '../misc/pki/cacert.crt')); - $template->assign("cert", $data); + if (!is_readable($ca_file)) + erreur("Impossible de lire le fichier"); + else + { + $data = openssl_x509_parse(file_get_contents(ONYX . '../misc/pki/cacert.crt')); + $template->assign("cert", $data); + } } return "admin/home"; diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index a8b328e5..aa28124d 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -6,8 +6,15 @@ include 'certificate.php'; if (!empty($_FILES["inputFile"]['tmp_name'])) { - //TODO use a variable to define the path - if (!file_exists(ONYX . "../misc/fic_pki/cacert.crt")) + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Please add the misc_dir variable into root.xml"); + return "admin/import_users"; + } + + if (!file_exists("$misc_dir/pki/cacert.crt")) { erreur("The root certificate file not found, please create this first"); return "admin/import_users"; From 30802be380e3540af4c8ecd713f1ecbca0690515 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 19:02:49 +0100 Subject: [PATCH 0112/2518] Fixed create or delete ca redirection page --- onyx/include/admin/certificate.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 89e9ca61..1fe836d7 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -70,7 +70,11 @@ if (!empty($p[2])) $dir = "$misc_dir/pki"; remove_directory($dir); } + + if ($p[2] == "deleteca" || $p[2] == "newca") + { + header("Location: /admin/"); + exit; + } } -header("Location: /admin/"); -exit; From e3f51487ab4d1c7e1d15642e8b31e30a76828475 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 19:18:51 +0100 Subject: [PATCH 0113/2518] Fixed client certificate generation --- onyx/include/admin/certificate.php | 10 +--------- onyx/include/admin/import_users.php | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 1fe836d7..c80b2a66 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -22,16 +22,8 @@ function remove_directory($dir) } } -function new_client($name) +function new_client($name, $misc_dir) { - if (isset($VAR['misc_dir'])) - $misc_dir = $VAR['misc_dir']; - else - { - erreur("Merci d'ajouter la variable misc_dir dans root.xml"); - return "admin/home"; - } - //TODO handle if already exist putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); putenv("TOP_DIR=$misc_dir/pki"); diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index aa28124d..76c4f292 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -72,7 +72,7 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) if (!empty($team->team_name)) { //TODO save the certificate subject - new_client($team->team_name); + new_client($team->team_name, $misc_dir); } } } From 7cf991d537f2df8bf02587e653632477103316ad Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 19:36:28 +0100 Subject: [PATCH 0114/2518] Add a textarea to show the output of the CA.sh --- misc/CA.sh | 20 +++++++++++++++----- onyx/include/admin/certificate.php | 1 + onyx/include/admin/import_users.php | 4 +++- onyx/tpl/bootstrap/admin/import_users.tpl | 5 +++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 1feb3e8c..6805446f 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -25,6 +25,8 @@ usage() [ $# -lt 1 ] && usage +OUTPUT=`mktemp` + case $1 in "-newca" ) # echo -e -n "${GREEN}Create the directories, take care this will delete" @@ -45,7 +47,11 @@ case $1 in sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF - pass=`pwgen 10 1` + pass=`pwgen 10 1` 2> $OUTPUT + if [ $? -ne 0 ]; then + cat $OUTPUT + exit 5 + fi openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ @@ -72,7 +78,7 @@ case $1 in echo -e "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -out server.crt -infiles server.csr if [ $? -ne 0 ]; then - echo -e "${RED}Signing failed${COLOR_RST}" + echo -e "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr exit 3 else @@ -94,7 +100,11 @@ case $1 in sed -i "s/=.*#COMMONNAME/= $2#COMMONNAME/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= client #CERTTYPE/" $OPENSSL_CONF - pass=`pwgen 10 1` + pass=`pwgen 10 1` 2> $OUTPUT + if [ $? -ne 0 ]; then + cat $OUTPUT + exit 5 + fi openssl req -batch -new -keyout ${2}.key -out ${2}.csr \ -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} @@ -103,14 +113,14 @@ case $1 in openssl ca -batch -policy policy_match -out ${2}.crt \ -config ${OPENSSL_CONF} -infiles ${2}.csr if [ $? -ne 0 ]; then - echo -e "${RED}Signing failed${COLOR_RST}" + echo -e "${RED}Signing failed for $2 ${COLOR_RST}" exit 3 fi # echo -e "${GREEN}Export the Client files to pkcs12${COLOR_RST}" openssl pkcs12 -export -inkey ${2}.key -in ${2}.crt -name ${2} \ -passin pass:$pass -out ${2}.p12 -passout pass:$pass if [ $? -ne 0 ]; then - echo -e "${RED}pkcs12 export failed${COLOR_RST}" + echo -e "${RED}pkcs12 export failed${COLOR_RST} for $2" exit 4 else echo -e "Exported pkcs12 file is ${2}.p12" diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index c80b2a66..24a8ddb7 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -28,6 +28,7 @@ function new_client($name, $misc_dir) putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); putenv("TOP_DIR=$misc_dir/pki"); $output = shell_exec("$misc_dir/CA.sh -newclient $name"); + return $output; } if (!empty($p[2])) diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index 76c4f292..b9b07dfc 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -31,6 +31,7 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) $elements = $xpath->query("//teams/team"); if (!is_null($elements)) { + $output = ""; foreach ($elements as $element) { $team = new Team(); @@ -72,9 +73,10 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) if (!empty($team->team_name)) { //TODO save the certificate subject - new_client($team->team_name, $misc_dir); + $output .= new_client($team->team_name, $misc_dir); } } + $template->assign("output", $output); } erreur("Fichier XML importé avec succès.", "success"); } diff --git a/onyx/tpl/bootstrap/admin/import_users.tpl b/onyx/tpl/bootstrap/admin/import_users.tpl index 73775932..72ed401c 100644 --- a/onyx/tpl/bootstrap/admin/import_users.tpl +++ b/onyx/tpl/bootstrap/admin/import_users.tpl @@ -10,4 +10,9 @@
+ +{if isset($output)} +

Output

+
{$output}
+{/if} {/block} From 04d96014092645071ffd26eda4b5c39c0fdb0ebb Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 20:59:22 +0100 Subject: [PATCH 0115/2518] Deleted heads bloc in layout and team.tpl --- onyx/tpl/bootstrap/admin/layout.tpl | 2 +- onyx/tpl/bootstrap/teams/team.tpl | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/onyx/tpl/bootstrap/admin/layout.tpl b/onyx/tpl/bootstrap/admin/layout.tpl index 393320ce..cf6b9d4a 100644 --- a/onyx/tpl/bootstrap/admin/layout.tpl +++ b/onyx/tpl/bootstrap/admin/layout.tpl @@ -3,7 +3,7 @@ {block name=head} {literal} {/literal} {/block} diff --git a/onyx/tpl/bootstrap/teams/team.tpl b/onyx/tpl/bootstrap/teams/team.tpl index 478e971e..eb92a925 100644 --- a/onyx/tpl/bootstrap/teams/team.tpl +++ b/onyx/tpl/bootstrap/teams/team.tpl @@ -1,9 +1,5 @@ {extends file="teams/layout.tpl"} -{block name=head} - -{/block} - {block name=content}

THIS IS TEAM From 3bd7654e81bd20eae821d4fdec13bea83f7e5d17 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 21:06:38 +0100 Subject: [PATCH 0116/2518] Delete href in logos and add Epita in the footer --- onyx/tpl/bootstrap/clock.tpl | 4 ---- onyx/tpl/bootstrap/layout.tpl | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/onyx/tpl/bootstrap/clock.tpl b/onyx/tpl/bootstrap/clock.tpl index 05c184c2..2b63efcb 100644 --- a/onyx/tpl/bootstrap/clock.tpl +++ b/onyx/tpl/bootstrap/clock.tpl @@ -1,13 +1,9 @@
    diff --git a/onyx/tpl/bootstrap/layout.tpl b/onyx/tpl/bootstrap/layout.tpl index 910a3a13..38523569 100644 --- a/onyx/tpl/bootstrap/layout.tpl +++ b/onyx/tpl/bootstrap/layout.tpl @@ -33,7 +33,8 @@
    From 124a7c2a32a017381357e5663e4a675a170d9be8 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 21:30:53 +0100 Subject: [PATCH 0117/2518] Fixed error ouput when pwgen was not found --- misc/CA.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 6805446f..a0133311 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -25,8 +25,6 @@ usage() [ $# -lt 1 ] && usage -OUTPUT=`mktemp` - case $1 in "-newca" ) # echo -e -n "${GREEN}Create the directories, take care this will delete" @@ -47,12 +45,14 @@ case $1 in sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF - pass=`pwgen 10 1` 2> $OUTPUT + type pwgen > /dev/null if [ $? -ne 0 ]; then - cat $OUTPUT + echo "command not found: pwgen" exit 5 fi + pass=`pwgen 10 1` + openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ -config $OPENSSL_CONF @@ -100,12 +100,14 @@ case $1 in sed -i "s/=.*#COMMONNAME/= $2#COMMONNAME/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= client #CERTTYPE/" $OPENSSL_CONF - pass=`pwgen 10 1` 2> $OUTPUT + type pwgen > /dev/null if [ $? -ne 0 ]; then - cat $OUTPUT + echo "command not found: pwgen" exit 5 fi + pass=`pwgen 10 1` + openssl req -batch -new -keyout ${2}.key -out ${2}.csr \ -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} From 62fca492ad7c2eaff2d5927c3390bc8d40b7775a Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Mon, 25 Nov 2013 23:06:26 +0100 Subject: [PATCH 0118/2518] Add timestamp comparison in ranking system --- onyx/include/common/Team.class.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 3a2cd470..30b9f343 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -5,7 +5,21 @@ if(!defined('ONYX')) exit; function cmp_team_pts($i1, $i2) { if ($i1->get_pts() == $i2->get_pts()){ - return 0; + $db = new BDD(); + + $timestampi1 = $db->unique_query("SELECT MAX( s.time ) AS maxTime + FROM solved AS s + WHERE s.id_team =".$i1); + $timestampi2 = $db->unique_query("SELECT MAX( s.time ) AS maxTime + FROM solved AS s + WHERE s.id_team =".$i12); + + $db->deconnexion(); + + if ($timestampi1 < $timestampi2){ + return 1 + else + return -1 } else{ return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; From 11dc0c153a6c73db3e12422970e37db846606b5c Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Tue, 26 Nov 2013 20:25:25 +0100 Subject: [PATCH 0119/2518] Fix some code errors that should not be commited yesterday... (sry) --- onyx/include/common/Team.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 30b9f343..0e3c9ffe 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -9,17 +9,17 @@ function cmp_team_pts($i1, $i2) $timestampi1 = $db->unique_query("SELECT MAX( s.time ) AS maxTime FROM solved AS s - WHERE s.id_team =".$i1); + WHERE s.id_team =".$i1->get_id()); $timestampi2 = $db->unique_query("SELECT MAX( s.time ) AS maxTime FROM solved AS s - WHERE s.id_team =".$i12); + WHERE s.id_team =".$i2->get_id()); $db->deconnexion(); - if ($timestampi1 < $timestampi2){ - return 1 + if ($timestampi1['maxTime'] > $timestampi2['maxTime']) + return 1; else - return -1 + return -1; } else{ return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; From 67b5422c28b1970849803fb8a8b86c68f698f166 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 28 Nov 2013 16:03:36 +0100 Subject: [PATCH 0120/2518] Deleted team/home Change the default page of team to summary page --- htdocs/index.php | 2 +- onyx/include/team/home.php | 8 -------- onyx/tpl/bootstrap/teams/home.tpl | 11 ----------- 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 onyx/include/team/home.php delete mode 100644 onyx/tpl/bootstrap/teams/home.tpl diff --git a/htdocs/index.php b/htdocs/index.php index 372a9adb..e451421d 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -108,7 +108,7 @@ else if ($n && $p[0] == SALT_USER) $template->assign("themes", Theme::get_themes()); if ($n <= 2) - $page = require("team/team.php"); + $page = require("team/summary.php"); else { switch($p[2]) diff --git a/onyx/include/team/home.php b/onyx/include/team/home.php deleted file mode 100644 index eaa60a72..00000000 --- a/onyx/include/team/home.php +++ /dev/null @@ -1,8 +0,0 @@ -assign("teams", Team::get_teams()); -$template->assign("top", Team::get_top()); - -return "teams/home"; diff --git a/onyx/tpl/bootstrap/teams/home.tpl b/onyx/tpl/bootstrap/teams/home.tpl deleted file mode 100644 index 5bcb3d87..00000000 --- a/onyx/tpl/bootstrap/teams/home.tpl +++ /dev/null @@ -1,11 +0,0 @@ -{extends file="teams/layout.tpl"} - -{block name=head} - -{/block} - -{block name=content} -

    - YOUPIII !!! -

    -{/block} From b406ae93e3b54721d6dacdc533efdae481fb788e Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 28 Nov 2013 16:28:43 +0100 Subject: [PATCH 0121/2518] Add team informations in the me page --- onyx/include/team/me.php | 2 ++ onyx/tpl/bootstrap/teams/me.tpl | 32 +++++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/onyx/include/team/me.php b/onyx/include/team/me.php index 053de859..b6a81f13 100644 --- a/onyx/include/team/me.php +++ b/onyx/include/team/me.php @@ -2,4 +2,6 @@ if(!defined('ONYX')) exit; +$template->assign("members", $TEAM->get_members()); + return "teams/me"; diff --git a/onyx/tpl/bootstrap/teams/me.tpl b/onyx/tpl/bootstrap/teams/me.tpl index eafc7f2c..bd05fbd7 100644 --- a/onyx/tpl/bootstrap/teams/me.tpl +++ b/onyx/tpl/bootstrap/teams/me.tpl @@ -1,7 +1,33 @@ {extends file="teams/layout.tpl"} {block name=content} -

    - THIS IS ME -

    +
    +
    +

    Information sur l'équipe

    +
    +
    + {if not empty($members)} + + + + + + + + + + {foreach from=$members item=member} + + + + + + + {/foreach} + +
    #PrénomNomPseudonymeEntreprise
    {$member->firstname}{$member->lastname}{$member->nickname}{$member->company}
    + {/if} +
    +
    + {/block} From 4f2dbf54703e7897cd725afc93dee5c12e18e8df Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 28 Nov 2013 17:01:31 +0100 Subject: [PATCH 0122/2518] Add progress bar in the me page Fixed class panel-body name in the me.tpl --- onyx/include/team/summary.php | 15 +++++++++++++++ onyx/tpl/bootstrap/teams/me.tpl | 2 +- onyx/tpl/bootstrap/teams/summary.tpl | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/onyx/include/team/summary.php b/onyx/include/team/summary.php index 4403c9ca..556a9298 100644 --- a/onyx/include/team/summary.php +++ b/onyx/include/team/summary.php @@ -2,7 +2,22 @@ if(!defined('ONYX')) exit; +$themes = Theme::get_themes(); +if (!empty($themes)) +{ + $max_exo = 0; + $res_exo = 0; + foreach($themes as $th) + { + $max_exo += $th->get_nb_exercices(); + //$res_exo += $TEAM->get_nb_res_exercices_by_theme($th->get_id()); + $res_exo += count($TEAM->get_solved_exercices($th->get_id())); + } + $percent = $res_exo * 100 / $max_exo; +} + $template->assign("themes", Theme::get_themes()); $template->assign("nbExoMax", Exercice::get_nb_exo_max()); +$template->assign("percent", $percent); return "teams/summary"; diff --git a/onyx/tpl/bootstrap/teams/me.tpl b/onyx/tpl/bootstrap/teams/me.tpl index bd05fbd7..7b73a58a 100644 --- a/onyx/tpl/bootstrap/teams/me.tpl +++ b/onyx/tpl/bootstrap/teams/me.tpl @@ -5,7 +5,7 @@

    Information sur l'équipe

    -
    +
    {if not empty($members)} diff --git a/onyx/tpl/bootstrap/teams/summary.tpl b/onyx/tpl/bootstrap/teams/summary.tpl index 944f6e13..cf025cba 100644 --- a/onyx/tpl/bootstrap/teams/summary.tpl +++ b/onyx/tpl/bootstrap/teams/summary.tpl @@ -1,5 +1,20 @@ {extends file="teams/layout.tpl"} {block name=content} +{if isset($percent)} +
    +
    +

    Progression

    +
    +
    +
    +
    + {$percent}% Complete +
    +
    +
    +
    +{/if} {include file="summary.tpl"} {/block} From dd766cf774e0c1a30df28a8757195cfd28dc70cb Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 28 Nov 2013 17:13:03 +0100 Subject: [PATCH 0123/2518] Team layout: change 'modifier' to 'info' --- onyx/tpl/bootstrap/teams/layout.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/teams/layout.tpl b/onyx/tpl/bootstrap/teams/layout.tpl index 15921f1b..6be3e306 100644 --- a/onyx/tpl/bootstrap/teams/layout.tpl +++ b/onyx/tpl/bootstrap/teams/layout.tpl @@ -39,7 +39,7 @@ $(document).ready(function() { + {if $teams} @@ -19,6 +20,9 @@ @@ -29,6 +33,7 @@ + {/foreach} From c067f6dbbe754471e5008a01df9f4b1876cda9a3 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 00:24:53 +0100 Subject: [PATCH 0141/2518] Fixed undefined var in admin/home.tpl --- onyx/tpl/bootstrap/admin/home.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/admin/home.tpl b/onyx/tpl/bootstrap/admin/home.tpl index 35c6d854..b9c60a39 100644 --- a/onyx/tpl/bootstrap/admin/home.tpl +++ b/onyx/tpl/bootstrap/admin/home.tpl @@ -16,7 +16,7 @@
  • [emailAddress] : {$cert['subject']['emailAddress']}
  • Supprimer - {elseif ! $cert_writable} + {elseif isset($cert_writable) && ! $cert_writable}
    Répertoire non accessible en écriture.
    Nouveau {else} From 745d8a8bd5e3196629c272b2728da1cb40408b9b Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 01:08:40 +0100 Subject: [PATCH 0142/2518] Fixed multiple team->update in import_users Show the pass at the end of import --- misc/CA.sh | 3 +-- onyx/include/admin/import_users.php | 13 +++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 45911707..1f23c18e 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -181,8 +181,7 @@ case $1 in echo -e "Exported pkcs12 file is ${2}.p12" fi mv ${2}.crt ${TOP_DIR}/certs -# TODO handle this file - echo "$2:$pass" >> teams.pass + echo "$2:$pass" >> ${TOP_DIR}/../teams.pass clean "client" $2 ;; "-revoke" ) diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index c143971c..dece7040 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -48,15 +48,15 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) else if ($child->nodeName == "member") { - if (!$team->update()) + // Slogan rly needed ? + if (empty($team->id) && !$team->update()) { - $error .= "Unable to add team $team->team_name
    "; - continue; + $error .= "Unable to add team $team->team_name
    "; + continue; } $user = new Member(); $user->team = $team; - foreach ($child->childNodes as $child_member) { if ($child_member->nodeName == "firstname") @@ -87,6 +87,11 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) $output .= new_client($team->team_name, $misc_dir); } } + if (file_exists("$misc_dir/teams.pass")) + { + $output .= file_get_contents("$misc_dir/teams.pass"); + unlink("$misc_dir/teams.pass"); + } $template->assign("output", $output); } From 3f0a403fd4c08869bdd7e3f80dcd41395057e593 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 01:17:30 +0100 Subject: [PATCH 0143/2518] Add some confirmation before delete user or revoke certificate --- onyx/tpl/bootstrap/admin/users.tpl | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 201c04a4..6c9f0aa0 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -19,10 +19,15 @@
    @@ -41,10 +46,13 @@ From 964d3b067f663e36fd2b6cd3dc20ff1fae5d3a48 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 19:21:32 +0100 Subject: [PATCH 0144/2518] Dont show generate certificate and revoke together --- onyx/tpl/bootstrap/admin/users.tpl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 6c9f0aa0..5cb1d126 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -21,13 +21,16 @@ {$t->id}
    + + + {if not $t->revoked} - - + {else} + {/if}
    From 31eabf84b468305cd3fe4aeeb50a5a30c988f773 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 19:40:47 +0100 Subject: [PATCH 0145/2518] Move the function remove_team from list_users.php to Team.class Revoke certificates after drop all teams --- onyx/include/admin/certificate.php | 15 ++++++++----- onyx/include/admin/list_users.php | 35 ++++++++++++++++++++---------- onyx/include/common/Team.class.php | 9 ++++++++ onyx/tpl/bootstrap/admin/users.tpl | 2 +- 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 23a35290..580d6b62 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -31,6 +31,13 @@ function new_client($name, $misc_dir) return $output; } +function revoke_client($name, $misc_dir) +{ + putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); + putenv("TOP_DIR=$misc_dir/pki"); + $output = shell_exec("$misc_dir/CA.sh -revoke $name"); +} + if (!empty($p[2])) { if (isset($VAR['misc_dir'])) @@ -60,11 +67,9 @@ if (!empty($p[2])) $name = $_GET['name']; if (isset($name)) { - putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("TOP_DIR=$misc_dir/pki"); - $output = shell_exec("$misc_dir/CA.sh -revoke $name"); - //TODO Check revocation failed - Team::set_revoked(TRUE, $name); + $output = revoke_client($name, $misc_dir); + //TODO Check revocation failed + Team::set_revoked(TRUE, $name); } } // Is new team diff --git a/onyx/include/admin/list_users.php b/onyx/include/admin/list_users.php index 3968bc16..3ac2871f 100644 --- a/onyx/include/admin/list_users.php +++ b/onyx/include/admin/list_users.php @@ -2,29 +2,40 @@ if(!defined('ONYX')) exit; -function remove_team($id) -{ - $db = new BDD(); - $db->query("DELETE FROM team_members WHERE id_team = ".$id); - $db->query("DELETE FROM solved WHERE id_team = ".$id); - $db->query("DELETE FROM teams WHERE id = ".$id); - $db->deconnexion(); -} +include 'certificate.php'; if (!empty($_GET["delete"])) { - $id_team = intval($_GET["delete"]); + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return SALT_ADMIN."/users"; + } - remove_team($id_team); + $id_team = intval($_GET["delete"]); + revoke_client($_GET['name'], $misc_dir); + Team::remove_team($id_team); header("Location: /".SALT_ADMIN."/teams"); exit; } else if (isset($_GET["drop"])) { + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return SALT_ADMIN."/users"; + } + foreach(Team::get_teams() as $team) { - remove_team($team->get_id()); + //TODO check output + revoke_client($team->team_name, $misc_dir); + Team::remove_team($team->get_id()); } header("Location: /".SALT_ADMIN."/teams"); @@ -33,4 +44,4 @@ else if (isset($_GET["drop"])) $template->assign("teams", Team::get_teams()); -return "admin/users"; \ No newline at end of file +return SALT_ADMIN."/users"; diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index d9b3a966..f2ba89e9 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -246,6 +246,15 @@ class Team return ($aff == 1); } + public static function remove_team($id) + { + $db = new BDD(); + $db->query("DELETE FROM team_members WHERE id_team = ".$id); + $db->query("DELETE FROM solved WHERE id_team = ".$id); + $db->query("DELETE FROM teams WHERE id = ".$id); + $db->deconnexion(); + } + public static function get_teams() { $db = new BDD(); diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 5cb1d126..3745aa70 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -19,7 +19,7 @@ - + From 854da4a12a08f4e5807e3ea0b9e09d35d08d085b Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 20:04:49 +0100 Subject: [PATCH 0147/2518] Change the icone download to floppy-save in the list_users page --- onyx/tpl/bootstrap/admin/users.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 3745aa70..387013bb 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -22,7 +22,7 @@ - + {if not $t->revoked} From ad5052bb992aaa94885cb354f5d35a240b990dfa Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 20:24:59 +0100 Subject: [PATCH 0148/2518] Add confimation to delete the root certificat --- onyx/tpl/bootstrap/admin/home.tpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/admin/home.tpl b/onyx/tpl/bootstrap/admin/home.tpl index b9c60a39..33a7366d 100644 --- a/onyx/tpl/bootstrap/admin/home.tpl +++ b/onyx/tpl/bootstrap/admin/home.tpl @@ -15,7 +15,8 @@
  • [CN] : {$cert['subject']['CN']}
  • [emailAddress] : {$cert['subject']['emailAddress']}
  • -
    Supprimer + Supprimer {elseif isset($cert_writable) && ! $cert_writable}
    Répertoire non accessible en écriture.
    Nouveau From 8f2edb704872c9d7cf8e472c87d3db628f2a11dd Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 20:29:59 +0100 Subject: [PATCH 0149/2518] Add catch NotFoundException in admin/exercice.php --- onyx/include/admin/exercice.php | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index fa6858cd..415e1901 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -4,17 +4,33 @@ if(!defined('ONYX')) exit; $p = $out[0]; -if (isset($p[2])) +//TODO maybe move the try catch to index.html ? +try { + if (isset($p[2])) + { $tmp = explode("-", $p[2]); $id = intval($tmp[0]); if ($id == 0) return "404"; $theme = new Theme($id); $template->assign("theme", $theme); + } + + if (isset($p[3])) + $template->assign("ex", new Exercice($p[3], $theme)); +} +catch (ThemeNotFoundException $e) +{ + return "404"; +} +catch(ExerciceNotFoundException $e) +{ + return "404"; +} +catch(ExerciceNotFoundException $e) +{ + return "404"; } -if (isset($p[3])) - $template->assign("ex", new Exercice($p[3], $theme)); - return SALT_ADMIN."/exercice"; From 4d1918a530e7837eab4db4da72c7089178d95cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Mon, 9 Dec 2013 11:54:06 +0100 Subject: [PATCH 0150/2518] Add a script for generating static site --- gen_site.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 gen_site.sh diff --git a/gen_site.sh b/gen_site.sh new file mode 100755 index 00000000..52544b99 --- /dev/null +++ b/gen_site.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +BASEURL="localhost" + +cd `dirname "$0"` + +mkdir -p out +cd out + +wget -c -m http://$BASEURL/ http://$BASEURL/connected/ From e2173a7d4474e7d26033a397992e1a1bd63cde78 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 11 Dec 2013 12:58:17 +0100 Subject: [PATCH 0151/2518] Modification for production --- htdocs/index.php | 7 +++++-- misc/openssl.cnf | 6 +++--- nginx.conf | 26 ++++++++++++++++++++------ onyx/config/sample.root.xml | 7 ++++++- onyx/tpl/bootstrap/clock.tpl | 6 +++--- onyx/tpl/bootstrap/layout.tpl | 6 +++--- 6 files changed, 40 insertions(+), 18 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index b14b78ba..0be26241 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -2,8 +2,9 @@ //Inclusion de l'API Onyx require_once(trim(file_get_contents('./.onyx'))); -define("SALT_USER", "connected"); -define("SALT_ADMIN", "admin"); +define("SALT_PUBLIC", $VAR["prefix_public"]); +define("SALT_USER", $VAR["prefix_teams"]); +define("SALT_ADMIN", $VAR["prefix_admin"]); //On active le débogage si l'on est sur le domaine de debug @@ -13,6 +14,8 @@ if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "fic" | //Chargement de tout le nécessaire pour le site require_once("common.php"); +$template->assign("SALT_CDN",SALT_PUBLIC); +$template->assign("SALT_PUBLIC",SALT_PUBLIC); $template->assign("SALT_USER",SALT_USER); $template->assign("SALT_ADMIN",SALT_ADMIN); diff --git a/misc/openssl.cnf b/misc/openssl.cnf index 95fa5f76..a8c067f9 100644 --- a/misc/openssl.cnf +++ b/misc/openssl.cnf @@ -39,7 +39,7 @@ default_ca = CA_default # The default ca section #################################################################### [ CA_default ] -dir = fic_pki #DIR # Where everything is kept +dir = /srv/fic2014-server/misc//pki #DIR # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. @@ -147,7 +147,7 @@ organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = SRS commonName = Common Name (e.g. server FQDN or YOUR name) -commonName_default = toto#COMMONNAME +commonName_default = FIC2014 Server #COMMONNAME commonName_max = 64 emailAddress = Email Address @@ -176,7 +176,7 @@ basicConstraints=CA:FALSE # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. -nsCertType = client #CERTTYPE +nsCertType = server #CERTTYPE # For an object signing certificate this would be used. # nsCertType = objsign diff --git a/nginx.conf b/nginx.conf index 1a4f42e1..b7fc7845 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,12 +1,26 @@ server { - listen 80; - listen [::]:80; - server_name fic fic.p0m.fr fic.nemunai.re; + listen 443 ssl; + listen [::]:443 ipv6only=on; access_log /var/log/nginx/fic.access_log; - error_log /var/log/nginx/fic.error_log debug; + error_log /var/log/nginx/fic.error_log; - root /var/www/fic2014-server/htdocs; + root /srv/fic2014-server/htdocs; + index index.php; + + ssl_certificate /srv/fic2014-server/misc/server.crt; + ssl_certificate_key /srv/fic2014-server/misc/server.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + ssl_client_certificate /srv/fic2014-server/misc/pki/cacert.crt; + ssl_verify_client on; + add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; + + if ($ssl_client_s_dn !~ "/C=FR/ST=France/O=Epita/OU=SRS/") + { + return 401; + } location / { if (-f $request_filename) { @@ -39,7 +53,7 @@ server { { if (!-e $document_root$document_uri) { return 404; } include /etc/nginx/fastcgi.conf; - fastcgi_pass 127.0.0.1:9000; + fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; break; } diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index e6291018..0491002f 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -1,8 +1,13 @@ - + 1381441316 + /srv/fic2014-server/misc/ + /srv/fic2014-server/submission/ ]]> + challenge-public + challenge + challenge-admin 0 diff --git a/onyx/tpl/bootstrap/clock.tpl b/onyx/tpl/bootstrap/clock.tpl index 10b4febb..7cbddfeb 100644 --- a/onyx/tpl/bootstrap/clock.tpl +++ b/onyx/tpl/bootstrap/clock.tpl @@ -1,11 +1,11 @@
      diff --git a/onyx/tpl/bootstrap/layout.tpl b/onyx/tpl/bootstrap/layout.tpl index 38523569..12be4bb4 100644 --- a/onyx/tpl/bootstrap/layout.tpl +++ b/onyx/tpl/bootstrap/layout.tpl @@ -5,7 +5,7 @@ {block name=title}Challenge FIC2014{/block} - + - + @@ -38,7 +38,7 @@ - + {block name=end}{/block} From 49554c01c8d9bfc3991c5fa109d584e228a74689 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 11 Dec 2013 12:58:20 +0100 Subject: [PATCH 0152/2518] Modification for production --- gen_site.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen_site.sh b/gen_site.sh index 52544b99..442b3511 100755 --- a/gen_site.sh +++ b/gen_site.sh @@ -7,4 +7,4 @@ cd `dirname "$0"` mkdir -p out cd out -wget -c -m http://$BASEURL/ http://$BASEURL/connected/ +wget -c -m https://$BASEURL/ https://$BASEURL/connected/ From c7d0f7d1e126f5085a5f671c47c96d3204aabb47 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 11 Dec 2013 17:20:26 +0100 Subject: [PATCH 0153/2518] Modification for two servers --- nginx-server-common.conf | 43 ++++++++++++++++++++++++ nginx-server.conf | 18 ++++++++++ nginx.conf | 66 ++++++++++++++++++------------------- onyx/config/sample.root.xml | 10 +++--- 4 files changed, 98 insertions(+), 39 deletions(-) create mode 100644 nginx-server-common.conf create mode 100644 nginx-server.conf diff --git a/nginx-server-common.conf b/nginx-server-common.conf new file mode 100644 index 00000000..c5d27bc7 --- /dev/null +++ b/nginx-server-common.conf @@ -0,0 +1,43 @@ + access_log /var/log/nginx/fic.access_log; + error_log /var/log/nginx/fic.error_log; + + root /var/www/fic2014-server/htdocs; + index index.php; + + add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; + + location / { + if (-f $request_filename) { + break; + } + if (-d $request_filename) { + break; + } + + rewrite ^/(.*)$ /index.php?p=$1 last; + } + + location ~* \favicon.ico$ { + access_log off; + expires 1d; + add_header Cache-Control public; + } + + location ~ ^/(img|js|css)/ { + access_log off; + expires 7d; + add_header Cache-Control public; + } + + location ~ /(\.ht|\.git|\.svn|\.onyx) { + return 403; + } + + location ~ .*.php$ + { + if (!-e $document_root$document_uri) { return 404; } + include /etc/nginx/fastcgi.conf; + fastcgi_pass unix:/var/run/fastcgi/php-fpm.sock; + fastcgi_index index.php; + break; + } diff --git a/nginx-server.conf b/nginx-server.conf new file mode 100644 index 00000000..ba338775 --- /dev/null +++ b/nginx-server.conf @@ -0,0 +1,18 @@ +server { + listen 443 ssl; + listen [::]:443 ipv6only=on ssl; + + ssl_certificate /var/www/fic2014-server/misc/server.crt; + ssl_certificate_key /var/www/fic2014-server/misc/server.key; +# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +# ssl_prefer_server_ciphers on; +# ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + + include /var/www/fic2014-server/nginx-server-common.conf; +} + +server { + listen [::1]:80 ipv6only=on; + + include /var/www/fic2014-server/nginx-server-common.conf; +} diff --git a/nginx.conf b/nginx.conf index b7fc7845..796a8d48 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,60 +1,58 @@ server { listen 443 ssl; - listen [::]:443 ipv6only=on; + listen [::]:443 ipv6only=on ssl; + + root /var/www/fic2014-server/htdocs/; access_log /var/log/nginx/fic.access_log; error_log /var/log/nginx/fic.error_log; - root /srv/fic2014-server/htdocs; - index index.php; - - ssl_certificate /srv/fic2014-server/misc/server.crt; - ssl_certificate_key /srv/fic2014-server/misc/server.key; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; - ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; - ssl_client_certificate /srv/fic2014-server/misc/pki/cacert.crt; - ssl_verify_client on; + ssl_certificate /var/www/fic2014-server/misc/server.crt; + ssl_certificate_key /var/www/fic2014-server/misc/server.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + ssl_client_certificate /var/www/fic2014-server/misc/pki/cacert.crt; + ssl_verify_client on; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; - if ($ssl_client_s_dn !~ "/C=FR/ST=France/O=Epita/OU=SRS/") + location / { - return 401; - } + default_type text/html; + if ($ssl_client_s_dn !~ "/C=FR/ST=France/O=Epita/OU=SRS/") + { + return 401; + } - location / { - if (-f $request_filename) { - break; - } - if (-d $request_filename) { - break; - } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Team1/") { + root /var/www/fic2014-server/htdocs/connected/166$1; - rewrite ^/(.*)$ /index.php?p=$1 last; + rewrite ^/submission-([0-9]+)-([0-9]+).html$ /submission.php?team=166&theme=$1&exercice=$2 last; + } } location ~* \favicon.ico$ { - access_log off; - expires 1d; - add_header Cache-Control public; + access_log off; + expires 1d; + add_header Cache-Control public; } location ~ ^/(img|js|css)/ { - access_log off; - expires 7d; - add_header Cache-Control public; + access_log off; + expires 7d; + add_header Cache-Control public; } location ~ /(\.ht|\.git|\.svn|\.onyx) { - deny all; + return 403; } - location ~ .*.php$ + location /submission.php { - if (!-e $document_root$document_uri) { return 404; } - include /etc/nginx/fastcgi.conf; - fastcgi_pass unix:/var/run/php5-fpm.sock; - fastcgi_index index.php; + root /var/www/fic2014-server/; + include /etc/nginx/fastcgi.conf; + fastcgi_pass unix:/var/run/fastcgi/php-fpm.sock; break; } + } diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index 0491002f..d94fd659 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -1,13 +1,13 @@ - + - 1381441316 - /srv/fic2014-server/misc/ - /srv/fic2014-server/submission/ - ]]> + 1386827772 + /var/www/fic2014-server/misc/ + /var/www/fic2014-server/submission/ challenge-public challenge challenge-admin + ]]> 0 From bc877802cc0aa47468a6a00bf3fec3df60cbc867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 11 Dec 2013 18:10:39 +0100 Subject: [PATCH 0154/2518] Start check submission script --- check.pl | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100755 check.pl diff --git a/check.pl b/check.pl new file mode 100755 index 00000000..2c12913a --- /dev/null +++ b/check.pl @@ -0,0 +1,80 @@ +#!/usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use DBI; + +use Data::Dumper; + +# First, read PHP configuration to extract some settings +my $profile; +my $submission_dir; + +open my $conf, "<", "onyx/config/root.xml"; +for my $p (<$conf>) +{ + if ($p =~ /<(?:option|var) name="(.*)">(.*)<\/(?:option|var)>/) + { + $profile = $2 if ($1 eq "profile"); + $submission_dir = $2 if ($1 eq "submission_dir"); + } +} +close $conf; + +die("No DB profile found") if ! $profile; +die("submission_dir is not a directory") if ! $submission_dir || ! -d $submission_dir; + +# Read db settings +my %db_settings; +open my $dbprof, "<", "onyx/db/$profile.profile.php"; +while (<$dbprof>) +{ + if (/\$___profile\[['"](.+)['"]\] = ['"](.+)['"]/) + { + $db_settings{$1} = $2; + } +} +close $dbprof; + +my $dbh; +# List all files to treat +opendir(my $dh, $submission_dir) || die "Can't opendir submission_dir: $!"; +for my $f (readdir $dh) +{ + if ($f =~ /^([0-9]+)-([0-9]+)-([0-9]+)$/) + { + my $team = $1; + my $theme = $2; + my $exercice = $3; + + open my $fh, "<", "$submission_dir/$f"; + my $solution = <$fh>; + close $fh; + + $dbh = DBI->connect("DBI:mysql:database=$db_settings{db};host=$db_settings{host};port=3306", + $db_settings{user}, $db_settings{pass}, + {'RaiseError' => 1, 'PrintError' => 1}) + or die $DBI::errstr if !$dbh; + + my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = ".int($exercice)); + + while (my $row = get_row($sth)) + { + say Dumper($row); + } + } +} +closedir $dh; + +$dbh->disconnect() if $dbh; + +sub query +{ + my $sth = $_[0]->prepare($_[1]); + $sth->execute(); + + die($_[0]->errstr) if (!$sth); + + return $sth; +} From 9109c3e3e019da5f89ce957ba2d6a2c5c75d6fd6 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 11 Dec 2013 18:11:32 +0100 Subject: [PATCH 0155/2518] Add gencrl into CA.sh --- misc/CA.sh | 34 ++++++++++++++++++++++++------ onyx/include/admin/certificate.php | 4 +++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 1f23c18e..aa0f6212 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -25,7 +25,7 @@ END_BOLD="" usage() { - echo "Usage: $0 (-newca|-newserver|-newclient NAME|-revoke NAME)" + echo "Usage: $0 (-newca|-newserver|-newclient NAME|-revoke NAME|-gencrl)" exit 1 } @@ -38,8 +38,9 @@ clean() mkdir -p ${TOP_DIR}/newcerts mkdir -p ${TOP_DIR}/private mkdir -p ${TOP_DIR}/pkcs + echo "01" > ${TOP_DIR}/crlnumber elif [ "$1" = "client" ]; then - rm -rf ${2}.key ${2}.csr + rm -rf ${TOP_DIR}/${2}.key ${TOP_DIR}/${2}.csr fi rm -rf $OUTPUT } @@ -151,7 +152,7 @@ case $1 in pass=`pwgen -n -B -y 12 1` - openssl req -batch -new -keyout ${2}.key -out ${2}.csr \ + openssl req -batch -new -keyout ${TOP_DIR}/${2}.key -out ${TOP_DIR}/${2}.csr \ -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT @@ -160,8 +161,8 @@ case $1 in fi echo -e "${GREEN}Signing the Client crt${COLOR_RST}" - openssl ca -batch -policy policy_match -out ${2}.crt \ - -config ${OPENSSL_CONF} -infiles ${2}.csr > $OUTPUT 2>&1 + openssl ca -batch -policy policy_match -out ${TOP_DIR}/${2}.crt \ + -config ${OPENSSL_CONF} -infiles ${TOP_DIR}/${2}.csr > $OUTPUT 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for $2 ${COLOR_RST}" cat $OUTPUT @@ -169,7 +170,7 @@ case $1 in exit 3 fi echo -e "${GREEN}Export the Client files to pkcs12${COLOR_RST}" - openssl pkcs12 -export -inkey ${2}.key -in ${2}.crt -name ${2} \ + openssl pkcs12 -export -inkey ${TOP_DIR}/${2}.key -in ${TOP_DIR}/${2}.crt -name ${2} \ -passin pass:$pass -out ${TOP_DIR}/pkcs/${2}.p12 \ -passout pass:$pass > $OUTPUT 2>&1 if [ $? -ne 0 ]; then @@ -180,8 +181,9 @@ case $1 in else echo -e "Exported pkcs12 file is ${2}.p12" fi - mv ${2}.crt ${TOP_DIR}/certs + mv ${TOP_DIR}/${2}.crt ${TOP_DIR}/certs echo "$2:$pass" >> ${TOP_DIR}/../teams.pass + echo "$pass" clean "client" $2 ;; "-revoke" ) @@ -200,7 +202,25 @@ case $1 in fi rm ${TOP_DIR}/certs/${2}.crt rm ${TOP_DIR}/pkcs/${2}.p12 + + echo -e "${GREEN}Generate crl.pem${COLOR_RST}" + openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + echo -e "${RED}Generate crl.pem failed" + cat $OUTPUT + exit 5 + fi + ;; + "-gencrl" ) + echo -e "${GREEN}Generate crl.pem${COLOR_RST}" + openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + echo -e "${RED}Generate crl.pem failed" + cat $OUTPUT + exit 5 + fi + ;; * ) usage ;; diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 580d6b62..5698f903 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -80,8 +80,10 @@ if (!empty($p[2])) //TODO check revoked attribute if (isset($name)) { - new_client($name, $misc_dir); + $output = new_client($name, $misc_dir); Team::set_revoked(FALSE, $name); + erreur($output, "sucess"); + return "admin/import_users"; } } elseif ($p[2] == "get") From 2b88c05dd77297235add38da2b700b3eeb3211ec Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 11 Dec 2013 18:12:12 +0100 Subject: [PATCH 0156/2518] Add ssl_crl in nginx.conf --- nginx.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nginx.conf b/nginx.conf index 796a8d48..5bcfbb8e 100644 --- a/nginx.conf +++ b/nginx.conf @@ -15,7 +15,8 @@ server { ssl_client_certificate /var/www/fic2014-server/misc/pki/cacert.crt; ssl_verify_client on; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; - + ssl_crl /var/www/fic2014-server/misc/pki/crl.pem; + location / { default_type text/html; From 812f87c22e57266fe1358ddb190142f06e33bae6 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Wed, 11 Dec 2013 19:16:51 +0100 Subject: [PATCH 0157/2518] Exercice.class.php: Fixed intval in exercice id --- onyx/include/common/Exercice.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index 8d8bf053..48010ae2 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -135,12 +135,14 @@ class Exercice do { array_push($checked, $exo); - $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = ".intval($exo)); + $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = ".$exo); $exo = $res['require']; $ret++; } while ($exo != "" && !in_array($exo, $checked)); $this->number = $ret; + + $db->deconnexion(); } function update($create) From b3beb516b05463d1d05c1766b737661067f94a4c Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Wed, 11 Dec 2013 19:18:45 +0100 Subject: [PATCH 0158/2518] Modify get_top for TOP3 themes --- onyx/include/common/Team.class.php | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index f2ba89e9..42f928ed 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -2,7 +2,7 @@ if(!defined('ONYX')) exit; -function cmp_team_pts($i1, $i2) +function cmp_team_pts($i1, $i2, $idTheme) { if ($i1->get_pts() == $i2->get_pts()){ $db = new BDD(); @@ -22,7 +22,7 @@ function cmp_team_pts($i1, $i2) return -1; } else{ - return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; + return ($i1->get_pts($idTheme) < $i2->get_pts($idTheme)) ? 1 : -1; } } @@ -147,17 +147,29 @@ class Team return $this->members; } - function get_pts() + function get_pts($themeID=-1) { if(!isset($this->points)) { $db = new BDD(); + $res = null; - $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points + if ($themeID != -1) + { + $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points FROM exercices E LEFT OUTER JOIN solved S ON E.id = S.id_exercice WHERE S.id_team = ".$this->id." GROUP BY S.id_team"); + } + else + { + $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points + FROM exercices E + LEFT OUTER JOIN solved S ON E.id = S.id_exercice + WHERE S.id_team = ".$this->id." AND E.id_theme = ".$themeID." + GROUP BY S.id_team"); + } $db->deconnexion(); @@ -269,11 +281,11 @@ class Team return $array; } - public static function get_top($nb=0) + public static function get_top($nb=0, $idTheme=-1) { $teams = Team::get_teams(); - usort($teams, "cmp_team_pts"); + usort($teams, "cmp_team_pts", $idTheme); if ($nb != 0) $teams = array_slice($teams, 0, $nb); From 60ec66ee2d9646b04b4e68ec78cc44f4e665d8a2 Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Thu, 12 Dec 2013 17:40:49 +0100 Subject: [PATCH 0159/2518] Summary display correction --- onyx/tpl/bootstrap/summary.tpl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index d0350e49..6c2572de 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -14,6 +14,7 @@
    {$sum=0} + {$cpt=0} {$themeID=$theme->get_id()} {$solved_exercices=$my_team->get_solved_exercices($themeID)} {foreach from=$theme->get_exercices_ordered() item=exo} @@ -30,8 +31,12 @@ {else} {/if} + {$cpt=$cpt+1} {/foreach} - + {for $i=$cpt to $nbExoMax-1} + + {/for} + {$total=$total+$sum} {/foreach} @@ -42,4 +47,4 @@ -
    Membres Points PlaceRévoqué
    {$t->id}
    + + +
    {$t->team_name} {$t->slogan}{$t->get_pts()} {$t->get_rank()}{if $t->revoked}Oui{else}Non{/if}
    {$t->id}
    - - - - + + + + + + + +
    {$t->team_name} {$t->slogan}
    - Importer + + Importer {if $teams} - Exporter - Vider + + Exporter + + Vider {/if}
    {$t->team_name} {$t->slogan}
    {$t->id}
    - + From 5656d116afe5c354f7e0ecd436ab69b34b0b7c9b Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 20:03:20 +0100 Subject: [PATCH 0146/2518] Fixed bad url in theme page --- onyx/include/admin/exercice.php | 13 ++++++++++--- onyx/tpl/bootstrap/admin/exercice.tpl | 12 ++++++++++-- onyx/tpl/bootstrap/admin/themes.tpl | 4 ++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index 3a925efb..fa6858cd 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -5,9 +5,16 @@ if(!defined('ONYX')) exit; $p = $out[0]; if (isset($p[2])) - $template->assign("theme", $p[2]); +{ + $tmp = explode("-", $p[2]); + $id = intval($tmp[0]); + if ($id == 0) + return "404"; + $theme = new Theme($id); + $template->assign("theme", $theme); +} if (isset($p[3])) - $template->assign("ex", $p[3]); + $template->assign("ex", new Exercice($p[3], $theme)); -return "admin/exercice"; +return SALT_ADMIN."/exercice"; diff --git a/onyx/tpl/bootstrap/admin/exercice.tpl b/onyx/tpl/bootstrap/admin/exercice.tpl index 1537536f..605034b2 100644 --- a/onyx/tpl/bootstrap/admin/exercice.tpl +++ b/onyx/tpl/bootstrap/admin/exercice.tpl @@ -1,7 +1,15 @@ {extends file="admin/layout.tpl"} {block name=content}

    - Theme: {$theme}
    - Exercice: {$ex} + Theme: {$theme->name}
    + {if isset($ex)} + Exercice: {$ex->id} + {else} +

      + {foreach $theme->get_exercices_ordered() as $ex} +
    • {$ex->get_name()}
    • + {/foreach} +
    + {/if}

    {/block} diff --git a/onyx/tpl/bootstrap/admin/themes.tpl b/onyx/tpl/bootstrap/admin/themes.tpl index 150ded87..86c9bf2b 100644 --- a/onyx/tpl/bootstrap/admin/themes.tpl +++ b/onyx/tpl/bootstrap/admin/themes.tpl @@ -19,10 +19,10 @@ Exporter
    {$t->name}{$t->name} FIXME
    {$theme->get_name()}{$pts}{$sum}{$sum}
    {$total}
    + \ No newline at end of file From 0f7c1bc7e9381838be0c4ba002e90d9762f9981c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 12 Dec 2013 16:43:01 +0100 Subject: [PATCH 0160/2518] Fixed sha1 Exercice.class --- onyx/include/common/Exercice.class.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index 48010ae2..df3cde50 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -16,6 +16,8 @@ class Exercice function Exercice($id=null, $theme=null) { + global $VAR; + if (!empty($id)) { $db = new BDD(); @@ -33,7 +35,13 @@ class Exercice // Decode sha1 if ($this->files) foreach($this->files as &$f) + { + $f["path_orig"] = $f["path"]; + if (isset($VAR["files_dir"])) + $f["path"] = $VAR["files_dir"].$f["path"]; + $f["basename"] = basename($f["path"]); $f["sha1"] = strhex($f["sha1"]); + } $this->keys = $db->query("SELECT `id`, `format`, `value` FROM exercice_keys @@ -135,7 +143,7 @@ class Exercice do { array_push($checked, $exo); - $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = ".$exo); + $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = '".$exo."'"); $exo = $res['require']; $ret++; } while ($exo != "" && !in_array($exo, $checked)); @@ -181,7 +189,7 @@ class Exercice $format = $key['format']; $value = $key['value']; if (isset($key['id'])) - $kid = intval($key['id']); + $kid = $key['id']; else $kid = 0; @@ -219,14 +227,14 @@ class Exercice if (!isset($file['id'])) { $db->query("INSERT INTO exercice_files - VALUES (NULL, '".$id."', '".$path."', '".$name."', '".$sha1."');"); + VALUES (NULL, '".$id."', '".$path."', '".$name."', UNHEX('".$sha1."'));"); $this->files[$k]['id'] = $db->insert_id(); } else { $db->query("UPDATE exercice_files - SET `path` = '".$path."', `name` = '".$name."', `sha1` = '".$sha1."' + SET `path` = '".$path."', `name` = '".$name."', `sha1` = UNHEX('".$sha1."') WHERE id = ".$fid); } } From 01624d389c56a069de6ec9678607e4eb5d027aa1 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 12 Dec 2013 17:00:35 +0100 Subject: [PATCH 0161/2518] Fixed themes drop --- onyx/include/admin/list_themes.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/onyx/include/admin/list_themes.php b/onyx/include/admin/list_themes.php index b8e40b76..5b74f0b9 100644 --- a/onyx/include/admin/list_themes.php +++ b/onyx/include/admin/list_themes.php @@ -8,9 +8,11 @@ function remove_themes($id) $res = $db->query("SELECT id FROM exercices WHERE id_theme = ".$id); foreach($res as $r) { - $db->query("DELETE FROM exercice_files WHERE id_exercice = ".$id); - $db->query("DELETE FROM exercice_keys WHERE id_exercice = ".$id); - $db->query("DELETE FROM solved WHERE id_exercice = ".$id); + $id_ex = $r['id']; + $db->escape($id_ex); + $db->query("DELETE FROM exercice_files WHERE id_exercice = '".$id_ex."'"); + $db->query("DELETE FROM exercice_keys WHERE id_exercice = '".$id_ex."'"); + $db->query("DELETE FROM solved WHERE id_exercice = '".$id_ex."'"); } $db->query("DELETE FROM exercices WHERE id_theme = ".$id); @@ -29,10 +31,13 @@ if (!empty($_GET["delete"])) } else if (isset($_GET["drop"])) { - foreach(Theme::get_themes() as $thm) - { - remove_themes($thm->get_id()); - } + $db = new BDD(); + $db->query("TRUNCATE exercice_files"); + $db->query("TRUNCATE exercice_keys"); + $db->query("TRUNCATE exercices"); + $db->query("TRUNCATE themes"); + $db->query("TRUNCATE solved"); + $db->deconnexion(); header("Location: /".SALT_ADMIN."/themes"); exit; @@ -40,4 +45,4 @@ else if (isset($_GET["drop"])) $template->assign("themes", Theme::get_themes()); -return "admin/themes"; \ No newline at end of file +return "admin/themes"; From 60f950dd6c1055b61b2bb94e8381db5594b42f70 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 12 Dec 2013 18:02:16 +0100 Subject: [PATCH 0162/2518] Add file_dir into sample.root.xml --- onyx/config/sample.root.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index d94fd659..4d05ed20 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -2,6 +2,7 @@ 1386827772 + /var/www/fic2014-server/files/ /var/www/fic2014-server/misc/ /var/www/fic2014-server/submission/ challenge-public From 4b101ef4b2f0e39865ee10b2fbae0808764c8cc6 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 12 Dec 2013 19:33:18 +0100 Subject: [PATCH 0163/2518] Modify public theme --- onyx/tpl/bootstrap/public/home.tpl | 5 ++--- onyx/tpl/bootstrap/public/layout.tpl | 1 - onyx/tpl/bootstrap/summary.tpl | 6 +++--- onyx/tpl/bootstrap/teams/exercice.tpl | 4 ++-- onyx/tpl/bootstrap/teams/theme.tpl | 4 ++-- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 6f0d757e..73af278d 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -1,9 +1,9 @@ {extends file="public/layout.tpl"} {block name=main} -
    +
    - +
    @@ -33,7 +33,6 @@ {/foreach}
    -
    {/block} diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index 1ce60ca4..d6022bdc 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -36,7 +36,6 @@ {foreach from=$teams item=my_team key=k}
    -

    {$my_team->get_name()}

    {include file="summary.tpl"}
    diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index 6c2572de..71b33b7c 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -1,7 +1,7 @@ - +
    - + {for $i=1 to $nbExoMax} {/for} @@ -47,4 +47,4 @@ -
    {$my_team->get_name()}Exercice {$i}{$total}
    \ No newline at end of file + diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index 387c43f8..f9151160 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -33,7 +33,7 @@ {if file_exists($file['path'])} - + @@ -56,7 +56,7 @@ {if $cur_exercice->has_solved($my_team)} Déjà résolu à {$cur_exercice->has_solved($my_team)|date_format:"%H:%M:%S"} :) {else} -
    +
    diff --git a/onyx/tpl/bootstrap/teams/theme.tpl b/onyx/tpl/bootstrap/teams/theme.tpl index 4b043282..14b4052f 100644 --- a/onyx/tpl/bootstrap/teams/theme.tpl +++ b/onyx/tpl/bootstrap/teams/theme.tpl @@ -6,9 +6,9 @@

    {foreach from=$cur_theme->get_exercices_ordered() item=exercice} {if $exercice->has_solved($my_team)} - {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} + {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} {elseif $exercice->is_unlocked($my_team)} - {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} + {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} {else} {$exercice->get_name()} {/if} From bbec08ac4ff80565fbe565f7167b0e5cb78b2b9f Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 13 Dec 2013 18:45:25 +0100 Subject: [PATCH 0164/2518] Server synchronisation --- check.pl | 58 +++++++++++++++++++++++++--- gen_site.sh | 83 +++++++++++++++++++++++++++++++++++++++- nginx-server-common.conf | 7 +++- nginx.conf | 41 +++++++++++++++----- submission.php | 24 ++++++++++++ synchro.sh | 23 +++++++++++ 6 files changed, 218 insertions(+), 18 deletions(-) create mode 100644 submission.php create mode 100755 synchro.sh diff --git a/check.pl b/check.pl index 2c12913a..9d88f259 100755 --- a/check.pl +++ b/check.pl @@ -4,14 +4,20 @@ use v5.10.1; use strict; use warnings; use DBI; +use File::Basename; -use Data::Dumper; +#Return number of good solutions +my $exit = 0; + +my $root = dirname(__FILE__); + +chdir($root); # First, read PHP configuration to extract some settings my $profile; my $submission_dir; -open my $conf, "<", "onyx/config/root.xml"; +open my $conf, "<", "$root/onyx/config/root.xml"; for my $p (<$conf>) { if ($p =~ /<(?:option|var) name="(.*)">(.*)<\/(?:option|var)>/) @@ -27,7 +33,7 @@ die("submission_dir is not a directory") if ! $submission_dir || ! -d $submissio # Read db settings my %db_settings; -open my $dbprof, "<", "onyx/db/$profile.profile.php"; +open my $dbprof, "<", "$root/onyx/db/$profile.profile.php"; while (<$dbprof>) { if (/\$___profile\[['"](.+)['"]\] = ['"](.+)['"]/) @@ -42,8 +48,10 @@ my $dbh; opendir(my $dh, $submission_dir) || die "Can't opendir submission_dir: $!"; for my $f (readdir $dh) { - if ($f =~ /^([0-9]+)-([0-9]+)-([0-9]+)$/) + if ($f =~ /^([0-9]+)-([0-9]+)-([a-zA-Z0-9_]+)$/) { + my $good = -1; + my $team = $1; my $theme = $2; my $exercice = $3; @@ -57,18 +65,51 @@ for my $f (readdir $dh) {'RaiseError' => 1, 'PrintError' => 1}) or die $DBI::errstr if !$dbh; - my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = ".int($exercice)); + my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = '$exercice';"); + # Check solutions while (my $row = get_row($sth)) { - say Dumper($row); + $good = 1 if ($good == -1); + + my $type = @$row[0]; + my $sol = @$row[1]; + + if ($type eq "raw" && $sol ne $solution) { + $good = 0; + last; + } + elsif ($type ne "raw") { + $good = 0; + warn "$type not implemented"; + last; + } } + + # Register solve + if ($good == -1) { + say "Exercice $exercice doesn't exist ; given by team $team in theme $theme."; + } + elsif ($good == 1) + { + say "Team $team solve exercice $exercice in $theme at ".localtime(); + query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, '$exercice', CURRENT_TIMESTAMP);"); + $exit++; + } + else { + say "Team $team didn't give the correct answer for exercice $exercice."; + } + + # Remove the file + unlink("$submission_dir/$f"); } } closedir $dh; $dbh->disconnect() if $dbh; +exit( $exit > 126 ? 126 : $exit ); + sub query { my $sth = $_[0]->prepare($_[1]); @@ -78,3 +119,8 @@ sub query return $sth; } + +sub get_row +{ + return $_[0]->fetchrow_arrayref(); +} diff --git a/gen_site.sh b/gen_site.sh index 442b3511..974eeb67 100755 --- a/gen_site.sh +++ b/gen_site.sh @@ -1,10 +1,91 @@ #!/bin/sh BASEURL="localhost" +SALT_TEAM="connected" +OUT_TEAM="./teams" + +MAX_PARAL=9 + +DEBUG=0 + cd `dirname "$0"` +if [ "$UID" = "0" ] +then + SCRIPT=`pwd`/`basename "$0"` + su -c "sh -c '$SCRIPT $@'" synchro + exit $? +fi + +if [ -f "/tmp/generate_site" ] +then + echo "This script is already running" 1>&2 + echo "Remove the file /tmp/generate_site if you are sure this is not true" 1>&2 + exit 1 +fi + +touch /tmp/generate_site + +WGET_OPT="--no-check-certificate -c" + +if [ $DEBUG -ne 1 ] +then + WGET_OPT="-q" +fi + mkdir -p out cd out -wget -c -m https://$BASEURL/ https://$BASEURL/connected/ +# First, remove existing version if any +rm -rf "$BASEURL" "$OUT_TEAM" + +wget $WGET_OPT -m -b "http://$BASEURL/" -o /dev/null + +mkdir -p "$BASEURL" +ln -sf "`pwd`/../files/" "$BASEURL/files" + +NB=0 +PIDLIST= +# Get list of teams and fetch them in parallel +for l in $(curl -k "http://$BASEURL/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/") +do + ( + wget $WGET_OPT -m "http://$BASEURL/$l" + + for m in $(grep -R " Date: Fri, 13 Dec 2013 18:48:13 +0100 Subject: [PATCH 0165/2518] Thursday release --- .gitignore | 1 + misc/openssl.cnf | 6 +++--- onyx/include/common/Team.class.php | 15 +++++++++------ onyx/include/common/Theme.class.php | 5 +++++ onyx/tpl/bootstrap/public/layout.tpl | 2 +- onyx/tpl/bootstrap/summary.tpl | 2 +- onyx/tpl/bootstrap/teams/me.tpl | 1 - 7 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index cb02566c..b1d213ad 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ onyx/config/root.xml onyx/db/*.profile.php onyx/tpl/*/*.html submission/* +misc/openssl.cnf diff --git a/misc/openssl.cnf b/misc/openssl.cnf index a8c067f9..a0183194 100644 --- a/misc/openssl.cnf +++ b/misc/openssl.cnf @@ -39,7 +39,7 @@ default_ca = CA_default # The default ca section #################################################################### [ CA_default ] -dir = /srv/fic2014-server/misc//pki #DIR # Where everything is kept +dir = /var/www/fic2014-server/misc//pki #DIR # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. @@ -147,7 +147,7 @@ organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = SRS commonName = Common Name (e.g. server FQDN or YOUR name) -commonName_default = FIC2014 Server #COMMONNAME +commonName_default = Groupe_8#COMMONNAME commonName_max = 64 emailAddress = Email Address @@ -176,7 +176,7 @@ basicConstraints=CA:FALSE # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. -nsCertType = server #CERTTYPE +nsCertType = client #CERTTYPE # For an object signing certificate this would be used. # nsCertType = objsign diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 42f928ed..83aae4e7 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -121,6 +121,10 @@ class Team return $this->team_name; } + function get_name_url() { + return urlencode($this->team_name); + } + function get_auth_level() { return $this->auth_level; } @@ -195,10 +199,10 @@ class Team function get_rank() { $teams = Team::get_top(); - for ($i = 0; $i < 10; $i++){ - $tid = $teams[$i]->get_id(); - if ($tid == $this->id) - return $i; + foreach($teams as $k => $t) + { + if ($t->get_id() == $this->id) + return $k + 1; } return 0; @@ -232,9 +236,8 @@ class Team $i = 0; if ($ids) { - foreach ($ids as $id){ + foreach ($ids as $id) $array[] = new Exercice($id['id_exercice']); - } } return $array; diff --git a/onyx/include/common/Theme.class.php b/onyx/include/common/Theme.class.php index 15f81d41..9ff832c4 100644 --- a/onyx/include/common/Theme.class.php +++ b/onyx/include/common/Theme.class.php @@ -60,6 +60,11 @@ class Theme return $this->name; } + function get_name_url() + { + return urlencode($this->name); + } + function get_id() { return $this->id; diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index d6022bdc..a71a787b 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -54,7 +54,7 @@ $(document).ready(function() { update_end(); $('#carousel-team').carousel({ - interval: 2000 }); + interval: 5000 }); setInterval( function() { update_end(); diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index 71b33b7c..e65c6d12 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -12,7 +12,7 @@ {$total=0} {foreach from=$themes item=theme} - {$theme->get_name()} + {$theme->get_name()} {$sum=0} {$cpt=0} {$themeID=$theme->get_id()} diff --git a/onyx/tpl/bootstrap/teams/me.tpl b/onyx/tpl/bootstrap/teams/me.tpl index 7b73a58a..ca4ec59d 100644 --- a/onyx/tpl/bootstrap/teams/me.tpl +++ b/onyx/tpl/bootstrap/teams/me.tpl @@ -9,7 +9,6 @@ {if not empty($members)} - From 134f6be772fb13ef6e97a2b3afa9c826c3177cc5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 13 Dec 2013 19:02:44 +0100 Subject: [PATCH 0166/2518] Disable the print of difficulty (always 0) --- onyx/tpl/bootstrap/teams/exercice.tpl | 1 - 1 file changed, 1 deletion(-) diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index f9151160..d07770c8 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -7,7 +7,6 @@
      -
    • Difficulté : {$cur_exercice->level}
    • Gain : {$cur_exercice->points}
    • Description : {$cur_exercice->statement}
    From 6cabc4003f2b9a4b38587f82b09bce3a11ac6b91 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 13 Dec 2013 20:03:04 +0100 Subject: [PATCH 0167/2518] Revert "Modify get_top for TOP3 themes" This reverts commit b3beb516b05463d1d05c1766b737661067f94a4c. --- onyx/include/common/Team.class.php | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 83aae4e7..35a48d45 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -2,7 +2,7 @@ if(!defined('ONYX')) exit; -function cmp_team_pts($i1, $i2, $idTheme) +function cmp_team_pts($i1, $i2) { if ($i1->get_pts() == $i2->get_pts()){ $db = new BDD(); @@ -22,7 +22,7 @@ function cmp_team_pts($i1, $i2, $idTheme) return -1; } else{ - return ($i1->get_pts($idTheme) < $i2->get_pts($idTheme)) ? 1 : -1; + return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; } } @@ -151,29 +151,17 @@ class Team return $this->members; } - function get_pts($themeID=-1) + function get_pts() { if(!isset($this->points)) { $db = new BDD(); - $res = null; - if ($themeID != -1) - { - $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points + $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points FROM exercices E LEFT OUTER JOIN solved S ON E.id = S.id_exercice WHERE S.id_team = ".$this->id." GROUP BY S.id_team"); - } - else - { - $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points - FROM exercices E - LEFT OUTER JOIN solved S ON E.id = S.id_exercice - WHERE S.id_team = ".$this->id." AND E.id_theme = ".$themeID." - GROUP BY S.id_team"); - } $db->deconnexion(); @@ -284,11 +272,11 @@ class Team return $array; } - public static function get_top($nb=0, $idTheme=-1) + public static function get_top($nb=0) { $teams = Team::get_teams(); - usort($teams, "cmp_team_pts", $idTheme); + usort($teams, "cmp_team_pts"); if ($nb != 0) $teams = array_slice($teams, 0, $nb); From 10eb72688fce178e42ee60f0c7a75eefdc7a78c7 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 13 Dec 2013 20:11:26 +0100 Subject: [PATCH 0168/2518] Add some check before solving exercice --- check.pl | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/check.pl b/check.pl index 9d88f259..4c87106b 100755 --- a/check.pl +++ b/check.pl @@ -65,7 +65,7 @@ for my $f (readdir $dh) {'RaiseError' => 1, 'PrintError' => 1}) or die $DBI::errstr if !$dbh; - my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = '$exercice';"); + my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = ".$dbh->quote($exercice)); # Check solutions while (my $row = get_row($sth)) @@ -88,16 +88,40 @@ for my $f (readdir $dh) # Register solve if ($good == -1) { - say "Exercice $exercice doesn't exist ; given by team $team in theme $theme."; + say localtime().": Exercice $exercice doesn't exist ; given by team $team in theme $theme."; } elsif ($good == 1) { - say "Team $team solve exercice $exercice in $theme at ".localtime(); - query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, '$exercice', CURRENT_TIMESTAMP);"); - $exit++; + # Check if the exercice exists + $sth = query($dbh, "SELECT `require` FROM exercices E WHERE E.id_theme = $theme AND E.id = ".$dbh->quote($exercice)); + if ($sth->rows && (my $row = get_row($sth))) + { + # Check if the team has solved dependancies + $sth = query($dbh, "SELECT COUNT(S.id) FROM solved S WHERE S.id_exercice = ".$dbh->quote(@$row[0])) if @$row[0]; + if (! (@$row[0] && $sth->rows)) + { + # Check if the team has not already solved this exercice + $sth = query($dbh, "SELECT COUNT(S.id) FROM solved S WHERE S.id_exercice = ".$dbh->quote($exercice)); + if (! $sth->rows) + { + say localtime().": Team $team solve exercice $exercice in $theme"; + query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, ".$dbh->quote($exercice).", CURRENT_TIMESTAMP);"); + $exit++; + } + else { + warn localtime().": Team $team try to solve exercice $exercice in $theme but ALREADY solved it"; + } + } + else { + warn localtime().": Team $team try to solve exercice $exercice in $theme but has NOT SOLVED required exercice ".@$row[0]; + } + } + else { + warn localtime().": Team $team try to solve exercice $exercice in $theme but does not exist"; + } } else { - say "Team $team didn't give the correct answer for exercice $exercice."; + say localtime().": Team $team didn't give the correct answer for exercice $exercice."; } # Remove the file From c349769425ada01d6755bec979393763e7695473 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 14 Dec 2013 06:11:14 +0100 Subject: [PATCH 0169/2518] Friday release --- check.pl | 17 +++--- clear_cache.sh | 15 +++++ gen_site.sh | 83 ++++++++++++++++++++++---- launch.sh | 53 ++++++++++++++++ nginx.conf | 1 + onyx/include/admin/list_themes.php | 2 + onyx/include/common/Exercice.class.php | 58 ++++++++++++++++-- onyx/include/common/Team.class.php | 47 ++++++++------- onyx/include/common/Theme.class.php | 19 +++++- onyx/require/cache.php | 31 ++++++---- onyx/tpl/bootstrap/public/home.tpl | 26 ++++++-- onyx/tpl/bootstrap/public/layout.tpl | 25 +++----- onyx/tpl/bootstrap/public/score.tpl | 1 - onyx/tpl/bootstrap/summary.tpl | 10 ++-- onyx/tpl/bootstrap/teams/exercice.tpl | 2 +- synchro.sh | 18 ++++-- 16 files changed, 319 insertions(+), 89 deletions(-) create mode 100755 clear_cache.sh create mode 100755 launch.sh diff --git a/check.pl b/check.pl index 4c87106b..147e5ca0 100755 --- a/check.pl +++ b/check.pl @@ -88,23 +88,26 @@ for my $f (readdir $dh) # Register solve if ($good == -1) { - say localtime().": Exercice $exercice doesn't exist ; given by team $team in theme $theme."; + say STDERR localtime().": Exercice $exercice doesn't exist ; given by team $team in theme $theme."; } elsif ($good == 1) { # Check if the exercice exists $sth = query($dbh, "SELECT `require` FROM exercices E WHERE E.id_theme = $theme AND E.id = ".$dbh->quote($exercice)); - if ($sth->rows && (my $row = get_row($sth))) + if ($sth->rows) { + my $row = get_row($sth); + # Check if the team has solved dependancies - $sth = query($dbh, "SELECT COUNT(S.id) FROM solved S WHERE S.id_exercice = ".$dbh->quote(@$row[0])) if @$row[0]; - if (! (@$row[0] && $sth->rows)) + $sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_exercice = ".$dbh->quote(@$row[0])) if @$row[0]; + if (! @$row[0] || $sth->rows) { # Check if the team has not already solved this exercice - $sth = query($dbh, "SELECT COUNT(S.id) FROM solved S WHERE S.id_exercice = ".$dbh->quote($exercice)); + $sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_exercice = ".$dbh->quote($exercice)); if (! $sth->rows) { - say localtime().": Team $team solve exercice $exercice in $theme"; + say $team; + say STDERR localtime().": Team $team solve exercice $exercice in $theme"; query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, ".$dbh->quote($exercice).", CURRENT_TIMESTAMP);"); $exit++; } @@ -121,7 +124,7 @@ for my $f (readdir $dh) } } else { - say localtime().": Team $team didn't give the correct answer for exercice $exercice."; + say STDERR localtime().": Team $team didn't give the correct answer for exercice $exercice."; } # Remove the file diff --git a/clear_cache.sh b/clear_cache.sh new file mode 100755 index 00000000..cb528dd4 --- /dev/null +++ b/clear_cache.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +cd `dirname "$0"` + +for n in "$@" +do + MD5=`echo -n $n | md5sum | cut -d " " -f 1` + if [ -f "onyx/cache/$MD5.cache.php" ] + then + rm -f "onyx/cache/$MD5.cache.php" + echo "--- $n deleted" + else + echo "/!\\ $n not found ($MD5)" + fi +done diff --git a/gen_site.sh b/gen_site.sh index 974eeb67..4667aea2 100755 --- a/gen_site.sh +++ b/gen_site.sh @@ -4,7 +4,7 @@ BASEURL="localhost" SALT_TEAM="connected" OUT_TEAM="./teams" -MAX_PARAL=9 +MAX_PARAL=10 DEBUG=0 @@ -34,8 +34,13 @@ then WGET_OPT="-q" fi +./clear_cache.sh top + mkdir -p out -cd out + +ORIG_DIR=`pwd` +MYTMPDIR=`mktemp -d` +cd "$MYTMPDIR" # First, remove existing version if any rm -rf "$BASEURL" "$OUT_TEAM" @@ -43,15 +48,38 @@ rm -rf "$BASEURL" "$OUT_TEAM" wget $WGET_OPT -m -b "http://$BASEURL/" -o /dev/null mkdir -p "$BASEURL" -ln -sf "`pwd`/../files/" "$BASEURL/files" +ln -sf "$ORIG_DIR/files/" "$BASEURL/files" + +# Get list of teams +TEAMS= +if [ $# -gt 0 ] +then + while [ $# -gt 0 ] + do + TEAMS="$TEAMS /$SALT_TEAM/$1/" + shift + done + FULLSYNC=0 +else + for l in $(curl -k "http://$BASEURL/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/") + do + TEAMS="$TEAMS $l" + done + FULLSYNC=1 +fi + +echo "Team list to generate: $TEAMS" NB=0 PIDLIST= -# Get list of teams and fetch them in parallel -for l in $(curl -k "http://$BASEURL/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/") +# Fetch them in parallel +for l in $TEAMS do ( - wget $WGET_OPT -m "http://$BASEURL/$l" + if ! wget $WGET_OPT -m "http://$BASEURL/$l" + then + exit 1 + fi for m in $(grep -R "&2 + exit $ERR + +else + MOREOPT= + if [ "$FULL" -eq "1" ] + then + MOREOPT="--delete" + fi + # Ok, now, sync files with prod + rsync -av $MOREOPT * "$ORIG_DIR/out" + + cd "$ORIG_DIR" + rm -rf "$MYTMPDIR" +fi diff --git a/launch.sh b/launch.sh new file mode 100755 index 00000000..5847e65c --- /dev/null +++ b/launch.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +cd `dirname "$0"` + +if [ "$UID" = "0" ] +then + SCRIPT=`pwd`/`basename "$0"` + su -c "sh $SCRIPT" synchro + exit $? +fi + +touch ./logs/checks.log +tail -f ./logs/checks.log & + +FULLREGEN=0 + +while true; +do + if [ "$FULLREGEN" != "0" ] + then + ./synchro.sh + else + ./synchro.sh delete + fi + + if [ `ls submission | wc -l` -gt 1 ] + then + TMPF=`mktemp` + if ! ./check.pl 2>> ./logs/checks.log > "$TMPF" + then + FULLREGEN=1 + fi + + if [ `cat "$TMPF" | wc -l` -gt 0 ] + then + while ! cat "$TMPF" | xargs ./gen_site.sh + do + echo "FAIL regeneration, retry..." 1>&2 + done + fi + rm "$TMPF" + + elif [ "$FULLREGEN" != "0" ] + then + while ! ./gen_site.sh; do + echo "FAIL regeneration, retry..." 1>&2 + done + FULLREGEN=0 + + else + sleep 1 + fi +done diff --git a/nginx.conf b/nginx.conf index 1ed8be7d..04144ca7 100644 --- a/nginx.conf +++ b/nginx.conf @@ -21,6 +21,7 @@ server { location / { default_type text/html; + expires epoch; set $team 0; diff --git a/onyx/include/admin/list_themes.php b/onyx/include/admin/list_themes.php index 5b74f0b9..a52a60f1 100644 --- a/onyx/include/admin/list_themes.php +++ b/onyx/include/admin/list_themes.php @@ -18,6 +18,8 @@ function remove_themes($id) $db->query("DELETE FROM exercices WHERE id_theme = ".$id); $db->query("DELETE FROM themes WHERE id = ".$id); $db->deconnexion(); + + Cache::del("ordered_th".$id); } if (!empty($_GET["delete"])) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index df3cde50..d74111f9 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -75,6 +75,23 @@ class Exercice } } + static function __set_state(array $array) + { + $tmp = new Exercice(); + + $tmp->id = $array["id"]; + $tmp->number = $array["number"]; + $tmp->theme = $array["theme"]; + $tmp->require = $array["require"]; + $tmp->level = $array["level"]; + $tmp->points = $array["points"]; + $tmp->statement = $array["statement"]; + $tmp->files = $array["files"]; + $tmp->keys = $array["keys"]; + + return $tmp; + } + function get_id() { return $this->id; @@ -89,10 +106,12 @@ class Exercice // trié par date function get_solved() { - $db = new BDD(); + $id = $this->id; + $db = new BDD(); + $db->escape($id); $res = $db->query("SELECT `id_team`, `time` FROM solved - WHERE id_exercice = '$this->id' + WHERE id_exercice = '$id' ORDER BY time"); $db->deconnexion(); @@ -105,11 +124,13 @@ class Exercice if ($this->require == "") return 1; - $db = new BDD(); + $req = $this->require; + $db = new BDD(); + $db->escape($req); $res = $db->unique_query("SELECT `id` FROM solved WHERE id_team = '".intval($team->id)."' - AND id_exercice = '$this->require'"); + AND id_exercice = '$req'"); $db->deconnexion(); if (empty($res)) return 0; @@ -118,9 +139,11 @@ class Exercice function has_solved($team) { - $db = new BDD(); + $id = $this->id; - $res = $db->unique_query("SELECT `time` FROM solved WHERE id_exercice = '$this->id' + $db = new BDD(); + $db->escape($id); + $res = $db->unique_query("SELECT `time` FROM solved WHERE id_exercice = '$id' AND id_team = ".intval($team->get_id())); $db->deconnexion(); @@ -143,6 +166,7 @@ class Exercice do { array_push($checked, $exo); + $db->escape($exo); $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = '".$exo."'"); $exo = $res['require']; $ret++; @@ -278,6 +302,28 @@ class Exercice return $res['max']; } + + public function first_to_solve_exercice() + { + $db = new BDD(); + + $id = $this->id; + $db->escape($id); + + $res = $db->unique_query("SELECT t3.team_name as result + FROM solved AS t1 + INNER JOIN ( + SELECT MIN(s.time) AS minTime + FROM solved AS s + WHERE s.id_exercice = '".$id."' + ) AS t2 + INNER JOIN teams AS t3 ON t1.id_team = t3.id + WHERE t1.time = t2.minTime"); + $db->deconnexion(); + + return $res['result']; + } + } class ExerciceNotFoundException extends Exception diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 35a48d45..88b4c8ec 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -60,6 +60,22 @@ class Team } } + static function __set_state(array $array) + { + $tmp = new Team(); + + $tmp->id = $array["id"]; + $tmp->team_name = $array["team_name"]; + $tmp->key_hash = $array["key_hash"]; + $tmp->auth_level = $array["auth_level"]; + $tmp->slogan = $array["slogan"]; + $tmp->members = $array["members"]; + $tmp->points = $array["points"]; + $tmp->revoked = $array["revoked"]; + + return $tmp; + } + // Class methods function update() { @@ -274,14 +290,20 @@ class Team public static function get_top($nb=0) { - $teams = Team::get_teams(); + $top = Cache::read("top"); + if (empty($top)) + { + $top = Team::get_teams(); - usort($teams, "cmp_team_pts"); + usort($top, "cmp_team_pts"); + + Cache::set("top", $top); + } if ($nb != 0) - $teams = array_slice($teams, 0, $nb); + $top = array_slice($top, 0, $nb); - return $teams; + return $top; } public static function get_nb_teams() @@ -292,21 +314,4 @@ class Team return $res['count_teams']; } - - public static function first_to_solve_exercice($id_exercice) - { - $db = new BDD(); - $res = $db->unique_query("SELECT t3.team_name as result - FROM solved AS t1 - INNER JOIN ( - SELECT MIN(s.time) AS minTime - FROM solved AS s - WHERE s.id_exercice = ".$id_exercice." - ) AS t2 - INNER JOIN teams AS t3 ON t1.id_team = t3.id - WHERE t1.time = t2.minTime"); - $db->deconnexion(); - - return $res['result']; - } } diff --git a/onyx/include/common/Theme.class.php b/onyx/include/common/Theme.class.php index 9ff832c4..c155fcb7 100644 --- a/onyx/include/common/Theme.class.php +++ b/onyx/include/common/Theme.class.php @@ -29,6 +29,16 @@ class Theme } } + static function __set_state(array $array) + { + $tmp = new Theme(); + + $tmp->id = $array["id"]; + $tmp->name = $array["name"]; + + return $tmp; + } + function update() { $name = $this->name; @@ -52,6 +62,8 @@ class Theme } $db->deconnexion(); + Cache::del("ordered_th".$this->id); + return ($aff == 1); } @@ -93,6 +105,10 @@ class Theme function get_exercices_ordered() { + $res = Cache::read("ordered_th".$this->id); + if (!empty($res)) + return $res; + $db = new BDD(); $res = $db->query("SELECT E.id, E.require FROM exercices E INNER JOIN themes T ON T.id = E.id_theme @@ -130,13 +146,14 @@ class Theme foreach($res as &$r) $r = new Exercice($r["id"]); + Cache::set("ordered_th".$this->id, $res); return $res; } public static function get_themes() { $db = new BDD(); - $ids = $db->query("SELECT `id` FROM `themes`"); + $ids = $db->query("SELECT `id` FROM `themes` ORDER BY `name`"); $db->deconnexion(); $array = array(); diff --git a/onyx/require/cache.php b/onyx/require/cache.php index 70564154..0971f736 100644 --- a/onyx/require/cache.php +++ b/onyx/require/cache.php @@ -2,34 +2,45 @@ class Cache { - + static function set($id,$var) { $file = ''; - - file_put_contents(ONYX.'cache/'.md5($id).'.cache.php',$file) or trigger_error('dossier cache inaccessible en écriture.',E_USER_ERROR); + + $tmpfname = tempnam("/tmp", "cache"); + + if(file_put_contents($tmpfname, $file, LOCK_EX) !== FALSE) + rename($tmpfname, ONYX.'cache/'.md5($id).'.cache.php') or trigger_error('dossier cache inaccessible en écriture.',E_USER_ERROR); + else + trigger_error('impossible d\'?crire dans '.$tmpfname,E_USER_ERROR); } - + static function read($id) { if(!is_readable(ONYX.'cache/'.md5($id).'.cache.php')) return FALSE; - - include(ONYX.'cache/'.md5($id).'.cache.php'); - if(!$cache) return FALSE; + + $tmpfname = tempnam("/tmp", "cache"); + copy(ONYX.'cache/'.md5($id).'.cache.php', $tmpfname); + + include($tmpfname); + + unlink($tmpfname); + + if(empty($cache)) return FALSE; return $cache; } - + static function del($id) { if(!is_file(ONYX.'cache/'.md5($id).'.cache.php')) return FALSE; return unlink(ONYX.'cache/'.md5($id).'.cache.php'); } - + static function flush() { foreach(glob(ONYX.'cache/*.cache.php') as $file) unlink($file); } - + } ?> \ No newline at end of file diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 73af278d..e97c2cef 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -1,9 +1,13 @@ {extends file="public/layout.tpl"} {block name=main} -
    - -
    # Prénom Nom Pseudonyme
    + {if isset($teams)} +
    @@ -21,7 +25,7 @@ {foreach from=$theme->get_exercices_ordered() item=exo} {$teamName=""} {for $i=0 to $nbExoMax} - {$teamName=Team::first_to_solve_exercice($exo->get_id())} + {$teamName=$exo->first_to_solve_exercice()} {/for} {if $teamName != ""} @@ -33,6 +37,20 @@ {/foreach}
    {$teamName}
    +

    +
    + {foreach from=$teams item=my_team key=k} +
    +
    + {include file="summary.tpl"} +
    + {/foreach} +
    +
    +{/if} + + + {/block} diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index a71a787b..da0bfa40 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -17,32 +17,23 @@ {/if}
    -
    +

    Top 10

    {foreach from=$top item=t key=k} -
    {$k+1}. {link href="{$t->id}-{$t->get_name()}" href_prefix="/" label=$t->get_name()}
    +
    {$k+1}. {link href="{$t->id}-{$t->get_name()}" href_prefix="/" label=$t->get_name()} + +{$t->get_pts()} + +
    {/foreach}
    -
    +
    {block name=main}{/block}
    -{if isset($teams)} - -{/if}
    {/block} @@ -54,7 +45,7 @@ $(document).ready(function() { update_end(); $('#carousel-team').carousel({ - interval: 5000 }); + interval: 10000 }); setInterval( function() { update_end(); diff --git a/onyx/tpl/bootstrap/public/score.tpl b/onyx/tpl/bootstrap/public/score.tpl index 5b113b44..1bfec7c4 100644 --- a/onyx/tpl/bootstrap/public/score.tpl +++ b/onyx/tpl/bootstrap/public/score.tpl @@ -2,7 +2,6 @@ {block name=main}
    -

    {$my_team->get_name()}

    {include file="summary.tpl"}
    {/block} diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index e65c6d12..1eed15df 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -1,7 +1,7 @@ - +
    - + {for $i=1 to $nbExoMax} {/for} @@ -12,7 +12,7 @@ {$total=0} {foreach from=$themes item=theme} - + {$sum=0} {$cpt=0} {$themeID=$theme->get_id()} @@ -43,8 +43,8 @@ - - + +
    {$my_team->get_name()}{$my_team->get_name()}Exercice {$i}
    {$theme->get_name()}{$theme->get_name()}
    Total :{$total}Total :{$total}
    diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index d07770c8..a487174c 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -8,7 +8,7 @@
    • Gain : {$cur_exercice->points}
    • -
    • Description : {$cur_exercice->statement}
    • +
    • Description : {$cur_exercice->statement|escape|nl2br}
    diff --git a/synchro.sh b/synchro.sh index 4ffc1ef3..9ea8a4b9 100755 --- a/synchro.sh +++ b/synchro.sh @@ -5,17 +5,23 @@ cd `dirname "$0"` if [ "$UID" = "0" ] then SCRIPT=`pwd`/`basename "$0"` - su -c "sh $SCRIPT" synchro + su -c "sh $SCRIPT $@" synchro exit $? fi -rsync -e ssh -av --delete out/localhost/* phobos:~/htdocs/ -rsync -e ssh -av --delete out/teams phobos:~/ -rsync -e ssh -av --delete files phobos:~/ -rsync -e ssh -av --delete misc phobos:~/ +OPTS= +if [ "$1" = "delete" ] +then + OPTS="$OPTS --delete" +fi + +rsync -e ssh -av $OPTS out/localhost/* phobos:~/htdocs/ +rsync -e ssh -av $OPTS out/teams phobos:~/ +rsync -e ssh -av $OPTS files phobos:~/ +rsync -e ssh -av $OPTS misc phobos:~/ scp nginx.conf submission.php phobos:~/ -rsync -e ssh -av --delete out/localhost/* phobos:~/htdocs/ +rsync -e ssh -av $OPTS out/localhost/* phobos:~/htdocs/ rsync -e ssh -av phobos:~/submission/ submission/ ssh phobos "rm ~/submission/*" From 7a42ea56b06d9a171a9ecc4e96d82ac1021f9abe Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 11 Jan 2014 17:02:46 +0100 Subject: [PATCH 0170/2518] Add refresh in public/home.tpl --- onyx/tpl/bootstrap/public/home.tpl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index e97c2cef..6751cbcf 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -1,5 +1,9 @@ {extends file="public/layout.tpl"} +{block name=head2} + +{/block} + {block name=main} {if isset($teams)} +{/block} From 147bb5be5567ca444037a7b8e87cc5ff940def82 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 10:43:16 +0100 Subject: [PATCH 0195/2518] Check localtime before check an answer --- check.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/check.pl b/check.pl index 2840f349..095af269 100755 --- a/check.pl +++ b/check.pl @@ -30,6 +30,17 @@ for my $p (<$conf>) } close $conf; +my $end_time = 1999999999; +if (-f "$root/misc/challenge_started") +{ + open my $conf, "<", "$root/misc/challenge_started"; + $end_time = <$conf>; + close $conf; + chomp($end_time); + $end_time += 14400; +} + +die("TIME expired!") if time() > $end_time; die("No DB profile found") if ! $profile; die("submission_dir is not a directory") if ! $submission_dir || ! -d $submission_dir; From 5b2b4265a4ca06736cc541f992fdfb655f6e3a21 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 10:58:59 +0100 Subject: [PATCH 0196/2518] Can use comm-socket with argument --- comm-socket.pl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/comm-socket.pl b/comm-socket.pl index e9c1b0f3..3748db21 100644 --- a/comm-socket.pl +++ b/comm-socket.pl @@ -7,12 +7,22 @@ use threads; die("Give at least the socket file as argument") if (! @ARGV); +my $sock_path = shift @ARGV; + my $socket = IO::Socket::UNIX->new( Type => SOCK_STREAM, - Peer => $ARGV[0], + Peer => $sock_path, ); -die "Can't create socket: $!" unless $socket; +die "Can't read socket ($sock_path): $!" unless $socket; + +if (@ARGV) +{ + while (my $arg = shift @ARGV) + { + say $socket $arg; + } +} my $s = IO::Select->new(); From 0774eb7009d5ffa0e61d0546043712cfb0cb41de Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 11:11:11 +0100 Subject: [PATCH 0197/2518] Fix obscur deletion in admin panel; add Whirlpool hash --- onyx/include/admin/exercice.php | 2 +- onyx/include/common/Exercice.class.php | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index c1d2b9ab..e4507cc8 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -2,7 +2,7 @@ if(!defined('ONYX')) exit; -$template->assign("fortyp", array("raw" => "RAW", "sha1" => "SHA-1", "md5" => "MD5", "sha224" => "SHA-224", "sha256" => "SHA-256", "sha384" => "SHA-384", "sha512" => "SHA-512")); +$template->assign("fortyp", array("raw" => "RAW", "sha1" => "SHA-1", "md5" => "MD5", "sha224" => "SHA-224", "sha256" => "SHA-256", "sha384" => "SHA-384", "sha512" => "SHA-512", "whirlpool" => "Whirlpool")); $p = $out[0]; diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index d01e8e93..7fade8d4 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -301,8 +301,11 @@ class Exercice function flush_keys() { + $id = $this->id; + $db = new BDD(); - $db->query("DELETE FROM exercice_keys WHERE id_exercice = ".intval($this->id)); + $db->escape($id); + $db->query("DELETE FROM exercice_keys WHERE id_exercice = '$id'"); $db->deconnexion(); $this->keys = array(); @@ -312,9 +315,9 @@ class Exercice { if ($format == "raw") { - $this->add_key("sha1", hash("sha1", $value)); + $this->add_key("sha256", hash("sha256", $value)); $this->add_key("sha512", hash("sha512", $value)); - $this->add_key("md5", hash("md5", $value)); + $this->add_key("whirlpool", hash("whirlpool", $value)); } else $this->keys[] = array( From 4304d7125d63bc3e3e58e3af69983265ce6f971d Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 15:50:00 +0100 Subject: [PATCH 0198/2518] Truncate exercice_tries --- onyx/include/admin/list_themes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/onyx/include/admin/list_themes.php b/onyx/include/admin/list_themes.php index a52a60f1..54800012 100644 --- a/onyx/include/admin/list_themes.php +++ b/onyx/include/admin/list_themes.php @@ -36,6 +36,7 @@ else if (isset($_GET["drop"])) $db = new BDD(); $db->query("TRUNCATE exercice_files"); $db->query("TRUNCATE exercice_keys"); + $db->query("TRUNCATE exercice_tries"); $db->query("TRUNCATE exercices"); $db->query("TRUNCATE themes"); $db->query("TRUNCATE solved"); From ebb0cabf9aa8acafbd23c3b10272f43142ea2cb8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 16:52:44 +0100 Subject: [PATCH 0199/2518] Change file path --- onyx/include/common/Exercice.class.php | 3 ++- onyx/tpl/bootstrap/teams/exercice.tpl | 2 +- synchro.sh | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index 7fade8d4..ad6a8b24 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -37,8 +37,9 @@ class Exercice foreach($this->files as &$f) { $f["path_orig"] = $f["path"]; + $f["path_hash"] = hash("sha384", $f["path"])."/".basename($f["path"]); if (isset($VAR["files_dir"])) - $f["path"] = $VAR["files_dir"].$f["path"]; + $f["path"] = $VAR["files_dir"].$f["path_hash"]; $f["basename"] = basename($f["path"]); $f["sha1"] = strhex($f["sha1"]); } diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index 3574f047..48ae7f99 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -32,7 +32,7 @@ {if file_exists($file['path'])} - + diff --git a/synchro.sh b/synchro.sh index 989d2bca..7bff0c25 100755 --- a/synchro.sh +++ b/synchro.sh @@ -15,11 +15,11 @@ then OPTS="$OPTS --delete" fi -rsync -e ssh -av $OPTS out/errors phobos:~/ -rsync -e ssh -av $OPTS out/htdocs phobos:~/ -rsync -e ssh -av $OPTS out/teams phobos:~/ -rsync -e ssh -av $OPTS files phobos:~/ -rsync -e ssh -av $OPTS misc phobos:~/ +rsync -e ssh -av $OPTS out/errors phobos:~/ +rsync -e ssh -av $OPTS out/htdocs phobos:~/ +rsync -e ssh -av $OPTS out/teams phobos:~/ +rsync -e ssh -avL $OPTS files phobos:~/ +rsync -e ssh -av $OPTS misc phobos:~/ scp nginx.conf submission.php phobos:~/ rsync -e ssh -av phobos:~/submission/ submission/ From 6f260045fa10f16104bae1a9aa067288096b3722 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:23:02 +0100 Subject: [PATCH 0200/2518] CA.sh: Add a Master CA --- misc/CA.sh | 75 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index aa0f6212..16d07dfd 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -11,17 +11,21 @@ fi CAKEY=./cakey.key CAREQ=./careq.csr CACERT=./cacert.crt +MASTERKEY=./master.key +MASTEREQ=./master.csr +MASTERCERT=./master.crt + DAYS=365 -#GREEN="\033[1;32m" -#RED="\033[1;31m" -#COLOR_RST="\033[0m" +GREEN="\033[1;32m" +RED="\033[1;31m" +COLOR_RST="\033[0m" -GREEN="" -RED="" -COLOR_RST="" -BOLD="" -END_BOLD="" +#GREEN="" +#RED="" +#COLOR_RST="" +#BOLD="" +#END_BOLD="" usage() { @@ -61,7 +65,7 @@ case $1 in ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') echo -e "${GREEN}Making CA key and csr${COLOR_RST}" - sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= FIC2014 MASTER #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= objsign #CERTTYPE/" $OPENSSL_CONF @@ -71,9 +75,37 @@ case $1 in exit 5 fi + # MASTER CA + sed -i 's/cacert\.crt/master\.crt/' $OPENSSL_CONF + sed -i 's/cakey\.key/master\.key/' $OPENSSL_CONF pass=`pwgen -n -B -y 12 1` + echo "Master pass: " $pass + openssl req -batch -new -keyout ${TOP_DIR}/private/${MASTERKEY} \ + -out ${TOP_DIR}/${MASTEREQ} -passout pass:$pass \ + -config $OPENSSL_CONF > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + cat $OUTPUT + clean "ca" + exit 4 + fi - openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ + echo -e "${GREEN}Self signes the MASTER certificate${COLOR_RST}" + openssl ca -batch -create_serial -out ${TOP_DIR}/${MASTERCERT} \ + -days ${DAYS} -keyfile ${TOP_DIR}/private/${MASTERKEY} \ + -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ + -infiles ${TOP_DIR}/${MASTEREQ} > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + cat $OUTPUT + clean "ca" + exit 4 + fi + + sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF + echo -e "${GREEN}Generate CA certificate${COLOR_RST}" + + pass=`pwgen -n -B -y 12 1` + echo "CA pass: " $pass + openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ -config $OPENSSL_CONF > $OUTPUT 2>&1 if [ $? -ne 0 ]; then @@ -90,17 +122,20 @@ case $1 in clean "ca" exit 4 fi - - echo -e "${GREEN}Self signes the CA certificate${COLOR_RST}" - openssl ca -batch -create_serial -out ${TOP_DIR}/${CACERT} \ - -days ${DAYS} -keyfile ${TOP_DIR}/private/${CAKEY} \ - -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ - -infiles ${TOP_DIR}/${CAREQ} > $OUTPUT 2>&1 + echo -e "${GREEN}Signing CA crt by Master${COLOR_RST}" + openssl ca -policy policy_match -config ${OPENSSL_CONF} \ + -out ${TOP_DIR}/${CACERT} -infiles ${TOP_DIR}/${CAREQ} if [ $? -ne 0 ]; then + echo -e "${RED}Signing failed for CA${COLOR_RST}" + rm -rf ${TOP_DIR}/${CACERT} ${TOP_DIR}/${CAKEY} ${TOP_DIR}/${CAREQ} cat $OUTPUT - clean "ca" + sed -i 's/master\.crt/cacert\.crt/' $OPENSSL_CONF + sed -i 's/master\.key/cakey\.key/' $OPENSSL_CONF exit 4 - fi + fi + + sed -i 's/master\.crt/cacert\.crt/' $OPENSSL_CONF + sed -i 's/master\.key/cakey\.key/' $OPENSSL_CONF ;; "-newserver" ) echo -e "${GREEN}Making the Server key and cert${COLOR_RST}" @@ -108,7 +143,7 @@ case $1 in echo -e "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi - sed -i 's/=.*#COMMONNAME/= FIC2014 Server #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= srs.epita.fr #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF openssl req -batch -new -keyout server.key -out server.csr \ -days ${DAYS} -config ${OPENSSL_CONF} > $OUTPUT 2>&1 @@ -118,7 +153,7 @@ case $1 in fi echo -e "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out server.crt -infiles server.csr > $OUTPUT 2>&1 + -out server.crt -infiles server.csr if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr From 63d73bc601e4177236292fb2a7e444dbe4edd8d8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:34:18 +0100 Subject: [PATCH 0201/2518] Fixed CA.sh path var --- misc/CA.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/CA.sh b/misc/CA.sh index 16d07dfd..9ba3878a 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -172,6 +172,9 @@ case $1 in echo "==============================================================" echo -e "${GREEN}Making the client key and csr of ${BOLD}${2}${END_BOLD}${COLOR_RST}" + ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') + sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF + if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then echo -e "${RED}Can not found the CA's key${COLOR_RST}" exit 2 From 83c61f6fe447ac8d0ea3372c95c23885f7516de7 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:44:46 +0100 Subject: [PATCH 0202/2518] misc/ --- synchro.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synchro.sh b/synchro.sh index 7bff0c25..07dea5ba 100755 --- a/synchro.sh +++ b/synchro.sh @@ -19,7 +19,7 @@ rsync -e ssh -av $OPTS out/errors phobos:~/ rsync -e ssh -av $OPTS out/htdocs phobos:~/ rsync -e ssh -av $OPTS out/teams phobos:~/ rsync -e ssh -avL $OPTS files phobos:~/ -rsync -e ssh -av $OPTS misc phobos:~/ +rsync -e ssh -av $OPTS misc/server.* misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ scp nginx.conf submission.php phobos:~/ rsync -e ssh -av phobos:~/submission/ submission/ From 363ba3325a94f27473bc6a790062f47c07f4e16f Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:59:15 +0100 Subject: [PATCH 0203/2518] Make some changes on chrono --- htdocs/index.php | 2 +- onyx/include/admin/chrono.php | 2 +- onyx/tpl/bootstrap/admin/exercice.tpl | 2 +- onyx/tpl/bootstrap/admin/home.tpl | 26 +++++++++++++++++++------- onyx/tpl/bootstrap/public/home.tpl | 2 +- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 1ae3750c..ac03ea5d 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -131,7 +131,7 @@ else if ($n && $p[0] == SALT_USER) $page = "teams/list"; } - else if (empty($VAR["start_challenge"]) || $VAR["start_challenge"] < time()) + else if (empty($VAR["start_challenge"])) { $TEAM = new Team($p[1]); $template->assign("my_team", $TEAM); diff --git a/onyx/include/admin/chrono.php b/onyx/include/admin/chrono.php index d62bc9c3..99350ee0 100644 --- a/onyx/include/admin/chrono.php +++ b/onyx/include/admin/chrono.php @@ -9,7 +9,7 @@ if (count($p) > 2) switch($p[2]) { case "start": - file_put_contents($VAR["misc_dir"]."/challenge_started", time() + 42); + file_put_contents($VAR["misc_dir"]."/challenge_started", time() + (intval($_POST["time"]) - 240) * 60); break; case "init": diff --git a/onyx/tpl/bootstrap/admin/exercice.tpl b/onyx/tpl/bootstrap/admin/exercice.tpl index 01de1461..affd82af 100644 --- a/onyx/tpl/bootstrap/admin/exercice.tpl +++ b/onyx/tpl/bootstrap/admin/exercice.tpl @@ -70,7 +70,7 @@
- {if is_file($file.path)} Calculated from {$file.path}: {sha1_file($file.path)}{/if} + {if is_file($file.path)} Calculated from {$file.path}: {sha1_file($file.path)} pas bon{else}label-success">ok{/if}{/if}
diff --git a/onyx/tpl/bootstrap/admin/home.tpl b/onyx/tpl/bootstrap/admin/home.tpl index 25101ae8..885c26fe 100644 --- a/onyx/tpl/bootstrap/admin/home.tpl +++ b/onyx/tpl/bootstrap/admin/home.tpl @@ -15,24 +15,36 @@
  • [CN] : {$cert['subject']['CN']}
  • [emailAddress] : {$cert['subject']['emailAddress']}
  • - Supprimer + {elseif isset($cert_writable) && ! $cert_writable}
    Répertoire non accessible en écriture.
    - Nouveau + {else} - Nouveau + Pas de certificat + {/if}
    -

    Chrono

    +

    Chrono Lancé{else}danger">Arrêté{/if}

    - Start - Réinitialiser + +
    + +
    + + minutes +
    +
    +
    + + Réinitialiser +
    +
    {/block} diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 6751cbcf..72f6efbe 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -1,7 +1,7 @@ {extends file="public/layout.tpl"} {block name=head2} - + {/block} {block name=main} From 9108124ca4ad3994dc762de4d4c6506e0c092973 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:59:49 +0100 Subject: [PATCH 0204/2518] Generate a directory for files --- gen_hash_link_files.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 gen_hash_link_files.sh diff --git a/gen_hash_link_files.sh b/gen_hash_link_files.sh new file mode 100755 index 00000000..2cb4873a --- /dev/null +++ b/gen_hash_link_files.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +FROM=`realpath $1`; shift +TO=`realpath $1`; shift + +if [ -z "$FROM" ] || [ -z "$TO" ] +then + echo "Usage: $0 from to" + exit 1 +elif ! [ -d "$FROM" ] +then + echo "$FROM not found" + exit 2 +fi + +mkdir -p "$TO" || exit 3 +rm -rf "$TO" || exit 3 + +for i in `find "$FROM" -mindepth 1 -type f` +do + FILE=`echo $i | sed "s!^$FROM/!!"` + HASH=`echo -n $FILE | sha384sum | cut -d " " -f 1` + + mkdir -p "$TO/$HASH/" + ln -s "$i" "$TO/$HASH/" +done From ac5aa1099e05c567ef8621d4ee4e4c013b8c24d8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 20:53:20 +0100 Subject: [PATCH 0205/2518] Revert "CA.sh: Add a Master CA" This reverts commit 6f260045fa10f16104bae1a9aa067288096b3722. --- misc/CA.sh | 79 +++++++++++++++--------------------------------------- 1 file changed, 22 insertions(+), 57 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 9ba3878a..3e7cc1cc 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -11,21 +11,17 @@ fi CAKEY=./cakey.key CAREQ=./careq.csr CACERT=./cacert.crt -MASTERKEY=./master.key -MASTEREQ=./master.csr -MASTERCERT=./master.crt - DAYS=365 -GREEN="\033[1;32m" -RED="\033[1;31m" -COLOR_RST="\033[0m" +#GREEN="\033[1;32m" +#RED="\033[1;31m" +#COLOR_RST="\033[0m" -#GREEN="" -#RED="" -#COLOR_RST="" -#BOLD="" -#END_BOLD="" +GREEN="" +RED="" +COLOR_RST="" +BOLD="" +END_BOLD="" usage() { @@ -65,7 +61,7 @@ case $1 in ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') echo -e "${GREEN}Making CA key and csr${COLOR_RST}" - sed -i 's/=.*#COMMONNAME/= FIC2014 MASTER #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= objsign #CERTTYPE/" $OPENSSL_CONF @@ -75,37 +71,9 @@ case $1 in exit 5 fi - # MASTER CA - sed -i 's/cacert\.crt/master\.crt/' $OPENSSL_CONF - sed -i 's/cakey\.key/master\.key/' $OPENSSL_CONF pass=`pwgen -n -B -y 12 1` - echo "Master pass: " $pass - openssl req -batch -new -keyout ${TOP_DIR}/private/${MASTERKEY} \ - -out ${TOP_DIR}/${MASTEREQ} -passout pass:$pass \ - -config $OPENSSL_CONF > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then - cat $OUTPUT - clean "ca" - exit 4 - fi - echo -e "${GREEN}Self signes the MASTER certificate${COLOR_RST}" - openssl ca -batch -create_serial -out ${TOP_DIR}/${MASTERCERT} \ - -days ${DAYS} -keyfile ${TOP_DIR}/private/${MASTERKEY} \ - -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ - -infiles ${TOP_DIR}/${MASTEREQ} > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then - cat $OUTPUT - clean "ca" - exit 4 - fi - - sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF - echo -e "${GREEN}Generate CA certificate${COLOR_RST}" - - pass=`pwgen -n -B -y 12 1` - echo "CA pass: " $pass - openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ + openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ -config $OPENSSL_CONF > $OUTPUT 2>&1 if [ $? -ne 0 ]; then @@ -122,20 +90,17 @@ case $1 in clean "ca" exit 4 fi - echo -e "${GREEN}Signing CA crt by Master${COLOR_RST}" - openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out ${TOP_DIR}/${CACERT} -infiles ${TOP_DIR}/${CAREQ} - if [ $? -ne 0 ]; then - echo -e "${RED}Signing failed for CA${COLOR_RST}" - rm -rf ${TOP_DIR}/${CACERT} ${TOP_DIR}/${CAKEY} ${TOP_DIR}/${CAREQ} - cat $OUTPUT - sed -i 's/master\.crt/cacert\.crt/' $OPENSSL_CONF - sed -i 's/master\.key/cakey\.key/' $OPENSSL_CONF - exit 4 - fi - sed -i 's/master\.crt/cacert\.crt/' $OPENSSL_CONF - sed -i 's/master\.key/cakey\.key/' $OPENSSL_CONF + echo -e "${GREEN}Self signes the CA certificate${COLOR_RST}" + openssl ca -batch -create_serial -out ${TOP_DIR}/${CACERT} \ + -days ${DAYS} -keyfile ${TOP_DIR}/private/${CAKEY} \ + -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ + -infiles ${TOP_DIR}/${CAREQ} > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + cat $OUTPUT + clean "ca" + exit 4 + fi ;; "-newserver" ) echo -e "${GREEN}Making the Server key and cert${COLOR_RST}" @@ -143,7 +108,7 @@ case $1 in echo -e "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi - sed -i 's/=.*#COMMONNAME/= srs.epita.fr #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= FIC2014 Server #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF openssl req -batch -new -keyout server.key -out server.csr \ -days ${DAYS} -config ${OPENSSL_CONF} > $OUTPUT 2>&1 @@ -153,7 +118,7 @@ case $1 in fi echo -e "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out server.crt -infiles server.csr + -out server.crt -infiles server.csr > $OUTPUT 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr From cc588d51f9103f9890c0821b2b091d01ae3ab91c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 03:07:52 +0100 Subject: [PATCH 0206/2518] Ready to generate new certificates --- check.pl | 5 + misc/CA.sh | 21 ++- misc/openssl.cnf | 218 ++++----------------------- nginx.conf | 15 +- onyx/tpl/bootstrap/public/layout.tpl | 4 +- submission.php | 10 +- synchro.sh | 3 +- 7 files changed, 67 insertions(+), 209 deletions(-) diff --git a/check.pl b/check.pl index 095af269..5b2863f9 100755 --- a/check.pl +++ b/check.pl @@ -110,6 +110,11 @@ for my $f (readdir $dh) elsif ($type eq "sha512") { $tmp_solution = sha512_hex($solution); } + elsif ($type eq "whirlpool") { + my $hash = Digest->new( 'Whirlpool' ); + $hash->add( $solution ); + $tmp_solution = $hash->hexdigest; + } elsif ($type ne "raw") { warn "$type not implemented"; } diff --git a/misc/CA.sh b/misc/CA.sh index 3e7cc1cc..db4ba6c4 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -11,7 +11,8 @@ fi CAKEY=./cakey.key CAREQ=./careq.csr CACERT=./cacert.crt -DAYS=365 + +DAYS=2 #GREEN="\033[1;32m" #RED="\033[1;31m" @@ -63,7 +64,6 @@ case $1 in echo -e "${GREEN}Making CA key and csr${COLOR_RST}" sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF - sed -i "s/=.*#CERTTYPE/= objsign #CERTTYPE/" $OPENSSL_CONF type pwgen > /dev/null if [ $? -ne 0 ]; then @@ -72,10 +72,9 @@ case $1 in fi pass=`pwgen -n -B -y 12 1` - openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ - -config $OPENSSL_CONF > $OUTPUT 2>&1 + -config $OPENSSL_CONF -extensions CORE_CA > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT clean "ca" @@ -94,7 +93,7 @@ case $1 in echo -e "${GREEN}Self signes the CA certificate${COLOR_RST}" openssl ca -batch -create_serial -out ${TOP_DIR}/${CACERT} \ -days ${DAYS} -keyfile ${TOP_DIR}/private/${CAKEY} \ - -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ + -selfsign -extensions CORE_CA -config ${OPENSSL_CONF} \ -infiles ${TOP_DIR}/${CAREQ} > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT @@ -108,17 +107,16 @@ case $1 in echo -e "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi - sed -i 's/=.*#COMMONNAME/= FIC2014 Server #COMMONNAME/' $OPENSSL_CONF - sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/=10.226.3.70#COMMONNAME/' $OPENSSL_CONF openssl req -batch -new -keyout server.key -out server.csr \ - -days ${DAYS} -config ${OPENSSL_CONF} > $OUTPUT 2>&1 + -days ${DAYS} -config ${OPENSSL_CONF} -extensions SERVER_SSL > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT exit 4 fi echo -e "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out server.crt -infiles server.csr > $OUTPUT 2>&1 + -out server.crt -extensions SERVER_SSL -infiles server.csr if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr @@ -145,7 +143,6 @@ case $1 in exit 2 fi sed -i "s/=.*#COMMONNAME/= $2#COMMONNAME/" $OPENSSL_CONF - sed -i "s/=.*#CERTTYPE/= client #CERTTYPE/" $OPENSSL_CONF type pwgen > /dev/null if [ $? -ne 0 ]; then @@ -156,7 +153,7 @@ case $1 in pass=`pwgen -n -B -y 12 1` openssl req -batch -new -keyout ${TOP_DIR}/${2}.key -out ${TOP_DIR}/${2}.csr \ - -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} > $OUTPUT 2>&1 + -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} -extensions CLIENT_SSL > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT clean "client" $2 @@ -165,7 +162,7 @@ case $1 in echo -e "${GREEN}Signing the Client crt${COLOR_RST}" openssl ca -batch -policy policy_match -out ${TOP_DIR}/${2}.crt \ - -config ${OPENSSL_CONF} -infiles ${TOP_DIR}/${2}.csr > $OUTPUT 2>&1 + -config ${OPENSSL_CONF} -extensions CLIENT_SSL -infiles ${TOP_DIR}/${2}.csr > $OUTPUT 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for $2 ${COLOR_RST}" cat $OUTPUT diff --git a/misc/openssl.cnf b/misc/openssl.cnf index a0183194..2cb594f2 100644 --- a/misc/openssl.cnf +++ b/misc/openssl.cnf @@ -55,8 +55,6 @@ crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.key # The private key RANDFILE = $dir/private/.rand # private random number file -x509_extensions = usr_cert # The extentions to add to the cert - # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options @@ -70,7 +68,7 @@ cert_opt = ca_default # Certificate field options # crlnumber must also be commented out to leave a V1 CRL. # crl_extensions = crl_ext -default_days = 365 # how long to certify for +default_days = 2 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = default # use public key default MD preserve = no # keep passed DN ordering @@ -147,7 +145,7 @@ organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = SRS commonName = Common Name (e.g. server FQDN or YOUR name) -commonName_default = Groupe_8#COMMONNAME +commonName_default =10.226.3.70#COMMONNAME commonName_max = 64 emailAddress = Email Address @@ -163,191 +161,37 @@ challengePassword_max = 20 unstructuredName = An optional company name -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -nsCertType = client #CERTTYPE - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "FIC 2014 generated certificates" - -# PKIX recommendations harmless if included in all certificates. +[CORE_CA] +nsComment = "FIC2014 CA" +basicConstraints = critical,CA:TRUE,pathlen:1 +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +issuerAltName = issuer:copy +keyUsage = keyCertSign, cRLSign +nsCertType = sslCA subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy -# An alternative to produce certificates that aren't -# deprecated according to PKIX. -# subjectAltName=email:move - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -# This is required for TSA certificates. -# extendedKeyUsage = critical,timeStamping - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - authorityKeyIdentifier=keyid:always,issuer -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always - -[ proxy_cert_ext ] -# These extensions should be added when creating a proxy certificate - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. +[SERVER_SSL] +nsComment = "FIC2014 Server" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +issuerAltName = issuer:copy +basicConstraints = critical,CA:FALSE +keyUsage = digitalSignature, keyEncipherment +nsCertType = server +extendedKeyUsage = serverAuth subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer +authorityKeyIdentifier=keyid:always,issuer -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy -# An alternative to produce certificates that aren't -# deprecated according to PKIX. -# subjectAltName=email:move - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -# This really needs to be in place for it to be a proxy certificate. -proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo - -#################################################################### -[ tsa ] - -default_tsa = tsa_config1 # the default TSA section - -[ tsa_config1 ] - -# These are used by the TSA reply generation only. -dir = ./demoCA # TSA root directory -serial = $dir/tsaserial # The current serial number (mandatory) -crypto_device = builtin # OpenSSL engine to use for signing -signer_cert = $dir/tsacert.pem # The TSA signing certificate - # (optional) -certs = $dir/cacert.pem # Certificate chain to include in reply - # (optional) -signer_key = $dir/private/tsakey.pem # The TSA private key (optional) - -default_policy = tsa_policy1 # Policy if request did not specify it - # (optional) -other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) -digests = md5, sha1 # Acceptable message digests (mandatory) -accuracy = secs:1, millisecs:500, microsecs:100 # (optional) -clock_precision_digits = 0 # number of digits after dot. (optional) -ordering = yes # Is ordering defined for timestamps? - # (optional, default: no) -tsa_name = yes # Must the TSA name be included in the reply? - # (optional, default: no) -ess_cert_id_chain = no # Must the ESS cert id chain be included? - # (optional, default: no) +[CLIENT_SSL] +nsComment = "FIC2014 Client" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +issuerAltName = issuer:copy +basicConstraints = critical,CA:FALSE +keyUsage = digitalSignature, nonRepudiation +nsCertType = client +extendedKeyUsage = clientAuth +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer diff --git a/nginx.conf b/nginx.conf index e7440406..6959d22b 100644 --- a/nginx.conf +++ b/nginx.conf @@ -2,6 +2,13 @@ server_tokens off; client_header_buffer_size 512; client_max_body_size 512; +server { + listen 80 default; + listen [::]:80 ipv6only=on default; + + rewrite ^ https://$host$uri; +} + server { listen 443 ssl; listen [::]:443 ipv6only=on ssl; @@ -13,14 +20,14 @@ server { access_log /var/log/nginx/fic.access_log; error_log /var/log/nginx/fic.error_log; - ssl_certificate /var/www/fic2014-server/misc/server.crt; - ssl_certificate_key /var/www/fic2014-server/misc/server.key; + ssl_certificate /var/www/fic2014-server/server.crt; + ssl_certificate_key /var/www/fic2014-server/server.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; - ssl_client_certificate /var/www/fic2014-server/misc/pki/cacert.crt; + ssl_client_certificate /var/www/fic2014-server/cacert.crt; ssl_verify_client optional; - ssl_crl /var/www/fic2014-server/misc/pki/crl.pem; + ssl_crl /var/www/fic2014-server/crl.pem; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index 6056acc6..8538e0ca 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -22,13 +22,13 @@

    Top 10

    {foreach from=$top item=t key=k} -
    {$k+1}. {link href="{$t->id}-{$t->get_name_url()}" href_prefix="/" label=$t->get_name()} +
    {$k+1}. {link href="{$t->id}-{$t->get_name_url()}" href_prefix="/" label={$t->get_name()|replace:"_":" et "}} {$t->get_pts()}
    {/foreach} -
        {link href="classement" href_prefix="/" label="Classement general"}
    +
        {link href="classement" href_prefix="/" label="Classement général"}
    diff --git a/submission.php b/submission.php index 85bffa3f..02f65569 100644 --- a/submission.php +++ b/submission.php @@ -8,7 +8,8 @@ function show($file) header("HTTP/1.1 403 Forbidden"); } -$file = __DIR__."/submission/".intval($_GET["team"])."-".intval($_GET["theme"])."-".urlencode($_GET["exercice"]); +$filename = intval($_GET["team"])."-".intval($_GET["theme"])."-".urlencode($_GET["exercice"]); +$file = __DIR__."/submission/".$filename; if (file_exists($file)) @@ -16,7 +17,12 @@ if (file_exists($file)) else if (!empty($_POST["solution"]) && !empty($_GET["team"]) && !empty($_GET["theme"]) && !empty($_GET["exercice"])) { - file_put_contents($file, $_POST['solution'], LOCK_EX); + $algos = array("md5", "sha1", "sha256", "sha384", "sha512", "whirlpool"); + $content = ""; + foreach($algos as $algo) + $content .= mcrypt_encrypt(MCRYPT_SERPENT_256, hash($algo, $_POST["solution"]), hash($algo, $filename), MCRYPT_MODE_ECB)."\n"; + + file_put_contents($file, $content, LOCK_EX); show(__DIR__."/teams/".intval($_GET["team"])."/".urlencode($_GET["theme"])."/".urlencode($_GET["exercice"])."/submission/index.html"); } diff --git a/synchro.sh b/synchro.sh index 07dea5ba..5f69615a 100755 --- a/synchro.sh +++ b/synchro.sh @@ -19,8 +19,7 @@ rsync -e ssh -av $OPTS out/errors phobos:~/ rsync -e ssh -av $OPTS out/htdocs phobos:~/ rsync -e ssh -av $OPTS out/teams phobos:~/ rsync -e ssh -avL $OPTS files phobos:~/ -rsync -e ssh -av $OPTS misc/server.* misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ -scp nginx.conf submission.php phobos:~/ +rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.* misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ rsync -e ssh -av phobos:~/submission/ submission/ ssh phobos "rm -fv ~/submission/*" From 8d7394b833e0442c638d15f4aa83bf5b49b584cb Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 03:08:08 +0100 Subject: [PATCH 0207/2518] New script to generate nginx.conf part --- check.pl | 74 ++++++++++++++++++----- launch.sh | 5 ++ nginx.conf | 34 ++++++++--- nginx_gen_team.sh | 3 + onyx/tpl/bootstrap/admin/export_teams.tpl | 2 +- submission.php | 17 +++++- synchro.sh | 2 +- 7 files changed, 108 insertions(+), 29 deletions(-) create mode 100644 nginx_gen_team.sh diff --git a/check.pl b/check.pl index 5b2863f9..92fd49ab 100755 --- a/check.pl +++ b/check.pl @@ -5,8 +5,40 @@ use strict; use warnings; use DBI; use File::Basename; -use Digest::MD5 qw(md5_hex); -use Digest::SHA qw(sha1_hex sha224_hex sha256_hex sha384_hex sha512_hex); +use Digest; +use Digest::MD5 qw(md5); +use Digest::SHA qw(sha1 sha224 sha256 sha384 sha512); +use Mcrypt qw(:ALGORITHMS :MODES :FUNCS); + +sub encrypt +{ + my ($algo, $key, $data, $mode) = @_; + + my $td = mcrypt_load( $algo, "", $mode, '' ); + mcrypt_init($td, $key, ""); + + my $encrypted = mcrypt_encrypt($td, $data); + + mcrypt_end($td); + + return $encrypted; +} + +sub my_crypt +{ + my ($key, $content) = @_; + + my $kfirst = pack('H*', substr($key, 0, 64)); + $content = encrypt(SERPENT, $kfirst, $content, ECB); + + if (length $key > 64) + { + my $ksec = pack('H*', substr($key, 64, 64)); + $content = encrypt(SERPENT, $ksec, $content, ECB); + } + + return unpack('H*', $content); +} #Return number of good solutions my $exit = 0; @@ -70,9 +102,18 @@ for my $f (readdir $dh) my $exercice = $3; open my $fh, "<", "$submission_dir/$f"; - my $solution = <$fh>; + my %solution; + $solution{md5} = <$fh>; chomp( $solution{md5} ); + $solution{sha1} = <$fh>; chomp( $solution{sha1} ); + $solution{sha256} = <$fh>; chomp( $solution{sha256} ); + $solution{sha384} = <$fh>; chomp( $solution{sha384} ); + $solution{sha512} = <$fh>; chomp( $solution{sha512} ); + $solution{whirlpool} = <$fh>; chomp( $solution{whirlpool} ); close $fh; + use Data::Dumper; + print STDERR Dumper(\%solution); + $dbh = DBI->connect("DBI:mysql:database=$db_settings{db};host=$db_settings{host};port=3306", $db_settings{user}, $db_settings{pass}, {'RaiseError' => 1, 'PrintError' => 1}) @@ -89,39 +130,40 @@ for my $f (readdir $dh) my $type = @$row[0]; my $sol = @$row[1]; - - my $tmp_solution = $solution; + my $filh; my $tmp_solution; if ($type eq "md5") { - $tmp_solution = md5_hex($solution); + $filh = md5($f); } elsif ($type eq "sha1") { - $tmp_solution = sha1_hex($solution); + $filh = sha1($f); } elsif ($type eq "sha224") { - $tmp_solution = sha224_hex($solution); + $filh = sha224($f); } elsif ($type eq "sha256") { - $tmp_solution = sha256_hex($solution); + $filh = sha256($f); } elsif ($type eq "sha384") { - $tmp_solution = sha384_hex($solution); + $filh = sha384($f); } elsif ($type eq "sha512") { - $tmp_solution = sha512_hex($solution); + $filh = sha512($f); } elsif ($type eq "whirlpool") { my $hash = Digest->new( 'Whirlpool' ); - $hash->add( $solution ); - $tmp_solution = $hash->hexdigest; + $hash->add( $f ); + $filh = $hash->digest; } - elsif ($type ne "raw") { + else { warn "$type not implemented"; } - say STDERR "check: $sol vs $tmp_solution"; + $tmp_solution = my_crypt($sol, $filh) if ($filh); - if ($sol ne $tmp_solution) + say STDERR "check $type: $solution{$type} vs $tmp_solution"; + + if ($solution{$type} ne $tmp_solution) { $good = 0; last; diff --git a/launch.sh b/launch.sh index eb2ee30a..eee62513 100755 --- a/launch.sh +++ b/launch.sh @@ -12,10 +12,12 @@ fi touch ./logs/checks.log tail -f ./logs/checks.log & +KP1=$! TMPF=`mktemp` tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -o ./out & +KP2=$! while ! [ -f /tmp/stop ]; do @@ -23,6 +25,7 @@ do if [ `ls submission | wc -l` -gt 1 ] then + ./clear_cache.sh top ./check.pl 2>> ./logs/checks.log >> "$TMPF" else @@ -30,4 +33,6 @@ do fi done +kill -9 $KP1 $KP2 + rm -rf "$TMPF" diff --git a/nginx.conf b/nginx.conf index 6959d22b..da0b2a10 100644 --- a/nginx.conf +++ b/nginx.conf @@ -45,15 +45,29 @@ server { set $team 0; - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=bombal_s/") { set $team 161; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_1/") { set $team 166; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_2/") { set $team 167; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_3/") { set $team 168; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_4/") { set $team 169; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_5/") { set $team 170; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_6/") { set $team 171; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_7/") { set $team 172; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_8/") { set $team 173; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Amin_Martin/") { set $team 343; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Bernard_Angoustures/") { set $team 344; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Cacace_Diallo/") { set $team 345; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Delaporte_Notebaert/") { set $team 346; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Dibe/") { set $team 347; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Dubief_Roccia/") { set $team 348; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Ezzahoui/") { set $team 349; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Fall/") { set $team 350; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Guerin_Chapiron/") { set $team 351; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Hugot_Hincelin/") { set $team 352; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Jawor_Giraud/") { set $team 353; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Konan/") { set $team 354; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Le_Mignan_Yadaba/") { set $team 355; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Michel-villaz_Gzenayi/") { set $team 356; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Muller_Perrin/") { set $team 357; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Pourcelot/") { set $team 358; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Quint_Kaczmarek/") { set $team 359; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Ruff_Czarny/") { set $team 360; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Sinet_Girault/") { set $team 361; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Therrode/") { set $team 362; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Sabono_Calmeji/") { set $team 363; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Renaud_Vandemeulebroucke/") { set $team 364; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=De_Priest_Tjonck/") { set $team 365; } if ($team) { root /var/www/fic2014-server/teams/$team$1; @@ -105,7 +119,7 @@ server { { root /var/www/fic2014-server/; - limit_rate 1k; + limit_rate 4k; include /etc/nginx/fastcgi.conf; fastcgi_pass unix:/var/run/php-fpm.sock; diff --git a/nginx_gen_team.sh b/nginx_gen_team.sh new file mode 100644 index 00000000..ebf28572 --- /dev/null +++ b/nginx_gen_team.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +curl http://localhost/admin/teams/export 2> /dev/null | grep "(.*)<.*$@ if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=\2/") { set $team \1; }@' diff --git a/onyx/tpl/bootstrap/admin/export_teams.tpl b/onyx/tpl/bootstrap/admin/export_teams.tpl index f9b47af1..7dc7767d 100644 --- a/onyx/tpl/bootstrap/admin/export_teams.tpl +++ b/onyx/tpl/bootstrap/admin/export_teams.tpl @@ -2,7 +2,7 @@ {foreach from=$teams item=t} - {$t->team_name} + {$t->team_name} {if $t->slogan}{$t->slogan}{/if} {if $t->get_members()} {foreach from=$t->get_members() item=m} diff --git a/submission.php b/submission.php index 02f65569..e9cf71fe 100644 --- a/submission.php +++ b/submission.php @@ -20,7 +20,22 @@ else if (!empty($_POST["solution"]) && !empty($_GET["team"]) && !empty($_GET["th $algos = array("md5", "sha1", "sha256", "sha384", "sha512", "whirlpool"); $content = ""; foreach($algos as $algo) - $content .= mcrypt_encrypt(MCRYPT_SERPENT_256, hash($algo, $_POST["solution"]), hash($algo, $filename), MCRYPT_MODE_ECB)."\n"; + { + $cnt = hash($algo, $filename, true); + // Encrypt twice on long key + $key = hash($algo, $_POST["solution"]); + + $kfirst = pack('H*', substr($key, 0, 64)); + $cnt = mcrypt_encrypt(MCRYPT_SERPENT, $kfirst, $cnt, MCRYPT_MODE_ECB); + + if (strlen($key) > 64) + { + $ksec = pack('H*', substr($key, 64, 64)); + $cnt = mcrypt_encrypt(MCRYPT_SERPENT, $ksec, $cnt, MCRYPT_MODE_ECB); + } + + $content .= bin2hex($cnt)."\n"; + } file_put_contents($file, $content, LOCK_EX); diff --git a/synchro.sh b/synchro.sh index 5f69615a..9406d1cd 100755 --- a/synchro.sh +++ b/synchro.sh @@ -19,7 +19,7 @@ rsync -e ssh -av $OPTS out/errors phobos:~/ rsync -e ssh -av $OPTS out/htdocs phobos:~/ rsync -e ssh -av $OPTS out/teams phobos:~/ rsync -e ssh -avL $OPTS files phobos:~/ -rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.* misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ +rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.crt misc/server.key misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ rsync -e ssh -av phobos:~/submission/ submission/ ssh phobos "rm -fv ~/submission/*" From 15a0c26b912ef5767e245b522b858333f7c1474c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 03:42:01 +0100 Subject: [PATCH 0208/2518] Add backup script --- backup.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100755 backup.sh diff --git a/backup.sh b/backup.sh new file mode 100755 index 00000000..120f5424 --- /dev/null +++ b/backup.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +cd `dirname "$0"` +TO_BCKP="/mnt/backup" + +chown synchro "$TO_BCKP" + +if [ "$UID" = "0" ] +then + SCRIPT=`pwd`/`basename "$0"` + su -c "sh $SCRIPT $@" synchro + exit $? +fi + +if mount | grep "$TO_BCKP" > /dev/null +then + + mysqldump -u backup --password="Riuy6of sae^W0Sh" fic2014 > "$TO_BCKP"/db-`date +%Y%m%d-%H%M`.sql + + rsync -avL true_files/ "$TO_BCKP" + rsync -avL logs/ "$TO_BCKP" + rsync -avL misc/ "$TO_BCKP" + rsync -avL .git "$TO_BCKP" + +else + echo No volume mount on $TO_BCKP +fi From d26e7826bd0f538d419e5ac13e52dfa982d95797 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 03:56:17 +0100 Subject: [PATCH 0209/2518] Better backups --- backup.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backup.sh b/backup.sh index 120f5424..84852fca 100755 --- a/backup.sh +++ b/backup.sh @@ -15,12 +15,13 @@ fi if mount | grep "$TO_BCKP" > /dev/null then - mysqldump -u backup --password="Riuy6of sae^W0Sh" fic2014 > "$TO_BCKP"/db-`date +%Y%m%d-%H%M`.sql + mysqldump -u backup --password="Riuy6of sae^W0Sh" fic2014 > "$TO_BCKP"/db/`date +%Y%m%d-%H%M`.sql - rsync -avL true_files/ "$TO_BCKP" - rsync -avL logs/ "$TO_BCKP" - rsync -avL misc/ "$TO_BCKP" + rsync -avL misc "$TO_BCKP" rsync -avL .git "$TO_BCKP" + rsync -avL logs "$TO_BCKP" + rsync -avL /var/log "$TO_BCKP" + rsync -avL true_files "$TO_BCKP" else echo No volume mount on $TO_BCKP From 0c33d83131dfba13f167f20e6ef2d385f082bf9c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 17:45:46 +0100 Subject: [PATCH 0210/2518] Fixed carousel --- onyx/tpl/bootstrap/public/home.tpl | 79 +++++++++++++--------------- onyx/tpl/bootstrap/public/layout.tpl | 6 ++- onyx/tpl/bootstrap/summary.tpl | 2 +- 3 files changed, 43 insertions(+), 44 deletions(-) diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 72f6efbe..395aebdd 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -5,56 +5,51 @@ {/block} {block name=main} - {if isset($teams)} +{if isset($teams)} {/if} - - - {/block} diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index 8538e0ca..e8aeb0e0 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -22,7 +22,7 @@

    Top 10

    {foreach from=$top item=t key=k} -
    {$k+1}. {link href="{$t->id}-{$t->get_name_url()}" href_prefix="/" label={$t->get_name()|replace:"_":" et "}} +
    {$k+1}. {link href="{$t->id}-{$t->get_name_url()}" href_prefix="/" label={$t->get_name()|replace:"_":" "}} {$t->get_pts()} @@ -46,5 +46,9 @@ var end_challenge = new Date({$END * 1000}); {/if} update_end(); + $(document).ready(function() { + $('#carousel-team').carousel({ + interval: 2000 }); + }); {/block} diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index 1eed15df..c7435bcf 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -1,7 +1,7 @@ - + {for $i=1 to $nbExoMax} {/for} From 939e6d994d323f6308bbcfb4e2346c0f5ad812f8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 17:49:17 +0100 Subject: [PATCH 0211/2518] Increase the time of each carousel item to 10000 --- onyx/tpl/bootstrap/public/layout.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index e8aeb0e0..98f98070 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -48,7 +48,7 @@ update_end(); $(document).ready(function() { $('#carousel-team').carousel({ - interval: 2000 }); + interval: 10000 }); }); {/block} From 21e4432fad1a5e59554dbc2540beb44b16d255f3 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 6 Jan 2016 19:30:57 +0100 Subject: [PATCH 0212/2518] Add frontend --- frontend/.gitignore | 1 + frontend/main.go | 33 ++++++++++++++++ frontend/submit.go | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 frontend/.gitignore create mode 100644 frontend/main.go create mode 100644 frontend/submit.go diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 00000000..1097e68b --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1 @@ +frontend diff --git a/frontend/main.go b/frontend/main.go new file mode 100644 index 00000000..2427f571 --- /dev/null +++ b/frontend/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" + "os" +) + +var SubmissionDir string + +func main() { + var bind = flag.String("bind", "0.0.0.0:8080", "Bind port/socket") + var prefix = flag.String("prefix", "", "Request path prefix to strip (from proxy)") + flag.StringVar(&SubmissionDir, "submission", "./submissions/", "Base directory where save submissions") + flag.Parse() + + log.Println("Creating submission directory...") + if _, err := os.Stat(SubmissionDir); os.IsNotExist(err) { + if err := os.MkdirAll(SubmissionDir, 0777); err != nil { + log.Fatal("Unable to create submission directory: ", err) + } + } + + log.Println("Registering handlers...") + http.Handle(fmt.Sprintf("%s/", *prefix), http.StripPrefix(*prefix, SubmissionHandler{})) + + log.Println(fmt.Sprintf("Ready, listening on %s", *bind)) + if err := http.ListenAndServe(*bind, nil); err != nil { + log.Fatal("Unable to listen and serve: ", err) + } +} diff --git a/frontend/submit.go b/frontend/submit.go new file mode 100644 index 00000000..2b66f644 --- /dev/null +++ b/frontend/submit.go @@ -0,0 +1,91 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" + "path" + "strconv" + "strings" +) + +type SubmissionHandler struct{} + +func (SubmissionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent()) + + w.Header().Set("Content-Type", "application/json") + + + // Check request type and size + if r.Method != "POST" { + http.Error(w, "{errmsg:\"Bad request.\"}", http.StatusBadRequest) + return + } else if r.ContentLength < 0 || r.ContentLength > 255 { + http.Error(w, "{errmsg:\"Request too large or request size unknown\"}", http.StatusRequestEntityTooLarge) + return + } + + + // Extract URL arguments + var sURL = strings.Split(r.URL.Path, "/") + + if len(sURL) != 3 && len(sURL) != 4 { + http.Error(w, "{errmsg:\"Bad request.\"}", http.StatusBadRequest) + return + } + + // Parse arguments + if team, err := strconv.Atoi(sURL[1]); err != nil { + http.Error(w, "{errmsg:\"Bad request.\"}", http.StatusBadRequest) + return + } else if exercice, err := strconv.Atoi(sURL[2]); err != nil { + http.Error(w, "{errmsg:\"Bad request.\"}", http.StatusBadRequest) + return + } else { + if _, err := os.Stat(path.Join(SubmissionDir, fmt.Sprintf("%d", team))); os.IsNotExist(err) { + log.Println("Creating submission directory for", team) + if err := os.MkdirAll(path.Join(SubmissionDir, fmt.Sprintf("%d", team)), 0777); err != nil { + log.Println("Unable to create submission directory: ", err) + http.Error(w, "{errmsg:\"Internal server error. Please retry in few seconds.\"}", http.StatusInternalServerError) + return + } + } + + + // Previous submission not treated + if _, err := os.Stat(path.Join(SubmissionDir, fmt.Sprintf("%d", team), fmt.Sprintf("%d", exercice))); !os.IsNotExist(err) { + http.Error(w, "{errmsg:\"Calm-down. A solution is already being processed.\"}", http.StatusPaymentRequired) + return + } + + + // Read request body + var body []byte + if r.ContentLength > 0 { + tmp := make([]byte, 1024) + for { + n, err := r.Body.Read(tmp) + for j := 0; j < n; j++ { + body = append(body, tmp[j]) + } + if err != nil || n <= 0 { + break + } + } + } + + + // Store content in file + if file, err := os.Create(path.Join(SubmissionDir, fmt.Sprintf("%d", team), fmt.Sprintf("%d", exercice))); err != nil { + log.Println("Unable to open exercice file:", err) + http.Error(w, "{errmsg:\"Internal server error. Please retry in few seconds.\"}", http.StatusInternalServerError) + return + } else { + file.Write(body) + file.Close() + } + http.Error(w, "{errmsg:\"Submission accepted, please wait...\"}", http.StatusAccepted) + } +} From a5dc600f28b5ba8192e0184136f0ea094ad30a96 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 18:27:53 +0100 Subject: [PATCH 0213/2518] Add API basis --- admin/api.go | 85 ++++++++++++++++++++++++++++++++++++++++++++ admin/api_version.go | 11 ++++++ admin/main.go | 27 ++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 admin/api.go create mode 100644 admin/api_version.go create mode 100644 admin/main.go diff --git a/admin/api.go b/admin/api.go new file mode 100644 index 00000000..349d5181 --- /dev/null +++ b/admin/api.go @@ -0,0 +1,85 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "log" + "net/http" + "strings" +) + +type DispatchFunction func([]string, []byte) (interface{}, error) + +var apiRouting = map[string]*(map[string]DispatchFunction){ + "version": &ApiVersionRouting, + //"images": &ApiImagesRouting, + //"users": &ApiUsersRouting, +} + +func ApiRouting(w http.ResponseWriter, r *http.Request) { + log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent()) + + // Extract URL arguments + var sURL = strings.Split(r.URL.Path, "/") + if sURL[len(sURL)-1] == "" && len(sURL) > 2 { + // Remove trailing / + sURL = sURL[:len(sURL)-1] + } + + w.Header().Set("Content-Type", "application/json") + + var ret interface{} + var err error = nil + + // Read the body + if r.ContentLength < 0 || r.ContentLength > 6553600 { + http.Error(w, fmt.Sprintf("{errmsg:\"Request too large or request size unknown\"}", err), http.StatusRequestEntityTooLarge) + return + } + var body []byte + if r.ContentLength > 0 { + tmp := make([]byte, 1024) + for { + n, err := r.Body.Read(tmp) + for j := 0; j < n; j++ { + body = append(body, tmp[j]) + } + if err != nil || n <= 0 { + break + } + } + } + + // Route request + if len(sURL) > 1 { + if h, ok := apiRouting[sURL[1]]; ok { + if f, ok := (*h)[r.Method]; ok { + ret, err = f(sURL[2:], body) + } else { + err = errors.New(fmt.Sprintf("Invalid action (%s) provided for %s.", r.Method, sURL[1])) + } + } + } else { + err = errors.New("No action provided.") + } + + // Format response + resStatus := http.StatusOK + if err != nil { + ret = map[string]string{"errmsg": err.Error()} + resStatus = http.StatusBadRequest + } + + if ret == nil { + ret = map[string]string{"errmsg": "Page not found"} + resStatus = http.StatusNotFound + } + + if j, err := json.Marshal(ret); err != nil { + http.Error(w, fmt.Sprintf("{errmsg:\"%q\"}", err), http.StatusInternalServerError) + } else { + w.WriteHeader(resStatus) + w.Write(j) + } +} diff --git a/admin/api_version.go b/admin/api_version.go new file mode 100644 index 00000000..9b4cbbfb --- /dev/null +++ b/admin/api_version.go @@ -0,0 +1,11 @@ +package main + +import () + +var ApiVersionRouting = map[string]DispatchFunction{ + "GET": showVersion, +} + +func showVersion(args []string, body []byte) (interface{}, error) { + return map[string]interface{}{"version": 0.1}, nil +} diff --git a/admin/main.go b/admin/main.go new file mode 100644 index 00000000..87b856fc --- /dev/null +++ b/admin/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" +) + +var SubmissionDir string +var BaseURL string + +func main() { + var bind = flag.String("bind", "0.0.0.0:8081", "Bind port/socket") + var _ = flag.String("db", "fic.db", "Path to the DB") + flag.StringVar(&BaseURL, "baseurl", "http://fic.srs.epita.fr/", "URL prepended to each URL") + flag.StringVar(&SubmissionDir, "submission", "./submissions/", "Base directory where save submissions") + flag.Parse() + + log.Println("Registering handlers...") + http.HandleFunc("/", ApiRouting) + + log.Println(fmt.Sprintf("Ready, listening on %s", *bind)) + if err := http.ListenAndServe(*bind, nil); err != nil { + log.Fatal("Unable to listen and serve: ", err) + } +} From abd5e2025ea4ce344668eadc39da20b90d7d9881 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 18:28:16 +0100 Subject: [PATCH 0214/2518] Add DB creation from schema --- admin/.gitignore | 2 + admin/db.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++ admin/main.go | 18 +++++++- 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 admin/.gitignore create mode 100644 admin/db.go diff --git a/admin/.gitignore b/admin/.gitignore new file mode 100644 index 00000000..6a514f21 --- /dev/null +++ b/admin/.gitignore @@ -0,0 +1,2 @@ +admin +fic.db diff --git a/admin/db.go b/admin/db.go new file mode 100644 index 00000000..0a8bc61e --- /dev/null +++ b/admin/db.go @@ -0,0 +1,109 @@ +package main + +import ( + "database/sql" + _ "github.com/mattn/go-sqlite3" +) + +var db *sql.DB + +func DBInit(path string) error { + var err error + if db, err = sql.Open("sqlite3", path); err != nil { + return err + } + + _, err = db.Exec(` +PRAGMA foreign_keys=ON; +`) + return err +} + +func DBCreate() error { + _, err := db.Exec(` +CREATE TABLE IF NOT EXISTS themes( + id_theme INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL +); +CREATE TABLE IF NOT EXISTS teams( + id_team INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL +); +CREATE TABLE IF NOT EXISTS team_certificates( + id_team INTEGER NOT NULL PRIMARY KEY, + revoked INTEGER NOT NULL, + FOREIGN KEY(id_team) REFERENCES teams(id_team) +); +CREATE TABLE IF NOT EXISTS team_members( + id_member INTEGER NOT NULL PRIMARY KEY, + id_team INTEGER, + firstname TEXT NOT NULL, + lastname TEXT NOT NULL, + nickname TEXT NOT NULL, + company TEXT NOT NULL, + FOREIGN KEY(id_team) REFERENCES teams(id_team) +); +CREATE TABLE IF NOT EXISTS exercices( + id_exercice INTEGER NOT NULL PRIMARY KEY, + id_theme INTEGER NOT NULL, + title TEXT NOT NULL, + statement TEXT NOT NULL, + hint TEXT NOT NULL, + depend INTEGER, + gain INTEGER NOT NULL, + video_uri TEXT NOT NULL, + FOREIGN KEY(id_theme) REFERENCES themes(id_theme), + FOREIGN KEY(depend) REFERENCES exercices(id_exercice) +); +CREATE TABLE IF NOT EXISTS exercice_files( + id_file INTEGER NOT NULL PRIMARY KEY, + path TEXT NOT NULL UNIQUE, + id_exercice INTEGER NOT NULL, + name TEXT NOT NULL, + sha1 BLOB NOT NULL, + FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice) +); +CREATE TABLE IF NOT EXISTS exercice_keys( + id_key INTEGER NOT NULL PRIMARY KEY, + id_exercice INTEGER NOT NULL, + type TEXT NOT NULL, + value BLOB NOT NULL, + FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice) +); +CREATE TABLE IF NOT EXISTS exercice_solved( + id_exercice INTEGER NOT NULL, + id_team INTEGER NOT NULL, + time TIMESTAMP NOT NULL, + FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice), + FOREIGN KEY(id_team) REFERENCES teams(id_team) +); +CREATE TABLE IF NOT EXISTS exercice_tries( + id_exercice INTEGER NOT NULL, + id_team INTEGER NOT NULL, + time TIMESTAMP NOT NULL, + FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice), + FOREIGN KEY(id_team) REFERENCES teams(id_team) +); +`) + return err +} + +func DBClose() error { + return db.Close() +} + +func DBPrepare(query string) (*sql.Stmt, error) { + return db.Prepare(query) +} + +func DBQuery(query string, args ...interface{}) (*sql.Rows, error) { + return db.Query(query, args...) +} + +func DBExec(query string, args ...interface{}) (sql.Result, error) { + return db.Exec(query, args...) +} + +func DBQueryRow(query string, args ...interface{}) *sql.Row { + return db.QueryRow(query, args...) +} diff --git a/admin/main.go b/admin/main.go index 87b856fc..1979ca64 100644 --- a/admin/main.go +++ b/admin/main.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "os" ) var SubmissionDir string @@ -12,11 +13,26 @@ var BaseURL string func main() { var bind = flag.String("bind", "0.0.0.0:8081", "Bind port/socket") - var _ = flag.String("db", "fic.db", "Path to the DB") + var dbfile = flag.String("db", "fic.db", "Path to the DB") flag.StringVar(&BaseURL, "baseurl", "http://fic.srs.epita.fr/", "URL prepended to each URL") flag.StringVar(&SubmissionDir, "submission", "./submissions/", "Base directory where save submissions") flag.Parse() + log.Println("Opening database...") + if err := DBInit(*dbfile); err != nil { + log.Fatal("Cannot open the database: ", err) + os.Exit(1) + + } + defer DBClose() + + log.Println("Creating database...") + if err := DBCreate(); err != nil { + log.Fatal("Cannot create database: ", err) + os.Exit(1) + + } + log.Println("Registering handlers...") http.HandleFunc("/", ApiRouting) From 6ec37b83ceb6917668543bcabf3042bb97d680f6 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 18:43:02 +0100 Subject: [PATCH 0215/2518] Add DB objects --- admin/api.go | 4 +-- admin/exercice.go | 83 +++++++++++++++++++++++++++++++++++++++++++++ admin/file.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++ admin/key.go | 69 ++++++++++++++++++++++++++++++++++++++ admin/member.go | 73 ++++++++++++++++++++++++++++++++++++++++ admin/team.go | 69 ++++++++++++++++++++++++++++++++++++++ admin/theme.go | 69 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 450 insertions(+), 2 deletions(-) create mode 100644 admin/exercice.go create mode 100644 admin/file.go create mode 100644 admin/key.go create mode 100644 admin/member.go create mode 100644 admin/team.go create mode 100644 admin/theme.go diff --git a/admin/api.go b/admin/api.go index 349d5181..0dd72256 100644 --- a/admin/api.go +++ b/admin/api.go @@ -13,8 +13,8 @@ type DispatchFunction func([]string, []byte) (interface{}, error) var apiRouting = map[string]*(map[string]DispatchFunction){ "version": &ApiVersionRouting, - //"images": &ApiImagesRouting, - //"users": &ApiUsersRouting, + //"themes": &ApiThemesRouting, + //"teams": &ApiTeamsRouting, } func ApiRouting(w http.ResponseWriter, r *http.Request) { diff --git a/admin/exercice.go b/admin/exercice.go new file mode 100644 index 00000000..988ec192 --- /dev/null +++ b/admin/exercice.go @@ -0,0 +1,83 @@ +package main + +import ( + "time" +) + +type Exercice struct { + id int64 + Title string + Statement string + Hint string + depend int64 + Gain int64 + VideoURI string +} + +func (t Theme) GetExercices() ([]Exercice, error) { + if rows, err := DBQuery("SELECT id_exercice, title, statement, hint, depend, gain, video_uri FROM teams WHERE id_theme = ?", t.id); err != nil { + return nil, err + } else { + defer rows.Close() + + var exos = make([]Exercice, 0) + for rows.Next() { + var e Exercice + if err := rows.Scan(&e.id, &e.Title, &e.Statement, &e.Hint, &e.depend, &e.Gain, &e.VideoURI); err != nil { + return nil, err + } + exos = append(exos, e) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return exos, nil + } +} + +func (t Theme) AddExercice(title string, statement string, hint string, depend *Exercice, gain int, videoURI string) (Exercice, error) { + if res, err := DBExec("INSERT INTO exercices (id_theme, title, statement, hint, depend, gain, video_uri) VALUES (?, ?, ?, ?, ?, ?, ?)", t.id, title, statement, hint, depend.id, gain, videoURI); err != nil { + return Exercice{}, err + } else if eid, err := res.LastInsertId(); err != nil { + return Exercice{}, err + } else { + return Exercice{eid, title, statement, hint, depend.id, int64(gain), videoURI}, nil + } +} + +func (e Exercice) Update() (int64, error) { + if res, err := DBExec("UPDATE exercices SET title = ?, statement = ?, hint = ?, depend = ?, gain = ?, video_uri = ? WHERE id_exercice = ?", e.Title, e.Statement, e.Hint, e.depend, e.Gain, e.VideoURI, e.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (e Exercice) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM exercices WHERE id_exercice = ?", e.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (e Exercice) NewTry(t Team) error { + if _, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time) VALUES (?, ?, ?)", e.id, t.id, time.Now()); err != nil { + return err + } else { + return nil + } +} + +func (e Exercice) Solved(t Team) error { + if _, err := DBExec("INSERT INTO exercice_solved (id_exercice, id_team, time) VALUES (?, ?, ?)", e.id, t.id, time.Now()); err != nil { + return err + } else { + return nil + } +} diff --git a/admin/file.go b/admin/file.go new file mode 100644 index 00000000..82728ef4 --- /dev/null +++ b/admin/file.go @@ -0,0 +1,85 @@ +package main + +import ( + "crypto/sha1" + "io" + "os" + "path" +) + +type EFile struct { + id int64 + Path string + id_exercice int64 + Name string + Checksum []byte +} + +func (e Exercice) GetFiles() ([]EFile, error) { + if rows, err := DBQuery("SELECT id_file, path, name, sha1 FROM exercice_files WHERE id_exercice = ?", e.id); err != nil { + return nil, err + } else { + defer rows.Close() + + var files = make([]EFile, 0) + for rows.Next() { + var f EFile + f.id_exercice = e.id + if err := rows.Scan(&f.id, &f.Path, &f.Name, &f.Checksum); err != nil { + return nil, err + } + files = append(files, f) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return files, nil + } +} + +func (e Exercice) ImportFile(filePath string) (EFile, error) { + if fd, err := os.Open(filePath); err != nil { + return EFile{}, err + } else { + defer fd.Close() + + hash := sha1.New() + if _, err := io.Copy(hash, fd); err != nil { + return EFile{}, err + } + + var result []byte + return e.AddFile(filePath, path.Base(filePath), hash.Sum(result)) + } +} + +func (e Exercice) AddFile(path string, name string, checksum []byte) (EFile, error) { + if res, err := DBExec("INSERT INTO exercice_files (id_exercice, path, name, sha1) VALUES (?, ?, ?, ?)", e.id, path, name, checksum); err != nil { + return EFile{}, err + } else if fid, err := res.LastInsertId(); err != nil { + return EFile{}, err + } else { + return EFile{fid, path, e.id, name, checksum}, nil + } +} + +func (f EFile) Update() (int64, error) { + if res, err := DBExec("UPDATE exercice_files SET id_exercice = ?, path = ?, name = ?, sha1 = ? WHERE id_file = ?", f.id_exercice, f.Path, f.Name, f.Checksum, f.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (f EFile) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM exercice_files WHERE id_file = ?", f.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} diff --git a/admin/key.go b/admin/key.go new file mode 100644 index 00000000..3052ddb7 --- /dev/null +++ b/admin/key.go @@ -0,0 +1,69 @@ +package main + +import ( + "crypto/sha512" +) + +type Key struct { + id int64 + id_exercice int64 + Type string + Value [64]byte +} + +func (e Exercice) GetKeys() ([]Key, error) { + if rows, err := DBQuery("SELECT id_key, type, value FROM exercice_keys WHERE id_exercice = ?", e.id); err != nil { + return nil, err + } else { + defer rows.Close() + + var keys = make([]Key, 0) + for rows.Next() { + var k Key + k.id_exercice = e.id + if err := rows.Scan(&k.id, &k.id_exercice, &k.Type, &k.Value); err != nil { + return nil, err + } + keys = append(keys, k) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return keys, nil + } +} + +func (e Exercice) AddRawKey(name string, raw_value string) (Key, error) { + return e.AddKey(name, sha512.Sum512([]byte(raw_value))) +} + +func (e Exercice) AddKey(name string, value [64]byte) (Key, error) { + if res, err := DBExec("INSERT INTO exercice_keys (id_exercice, type, value) VALUES (?, ?, ?)", e.id, name, value); err != nil { + return Key{}, err + } else if kid, err := res.LastInsertId(); err != nil { + return Key{}, err + } else { + return Key{kid, e.id, name, value}, nil + } +} + +func (k Key) Update() (int64, error) { + if res, err := DBExec("UPDATE exercice_keys SET id_exercice = ?, type = ?, value = ? WHERE id_key = ?", k.id_exercice, k.Type, k.Value, k.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (k Key) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM exercice_keys WHERE id_key = ?", k.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} diff --git a/admin/member.go b/admin/member.go new file mode 100644 index 00000000..5de67e41 --- /dev/null +++ b/admin/member.go @@ -0,0 +1,73 @@ +package main + +import () + +type Member struct { + id int64 + Firstname string + Lastname string + Nickname string + Company string +} + +func (t Team) GetMembers() ([]Member, error) { + if rows, err := DBQuery("SELECT id_member, firstname, lastname, nickname, company FROM team_members WHERE id_team = ?", t.id); err != nil { + return nil, err + } else { + defer rows.Close() + + var members = make([]Member, 0) + for rows.Next() { + var m Member + if err := rows.Scan(&m.id, &m.Firstname, &m.Lastname, &m.Nickname, &m.Company); err != nil { + return nil, err + } + members = append(members, m) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return members, nil + } +} + +func (t Team) AddMember(firstname string, lastname string, nickname string, company string) (Member, error) { + if res, err := DBExec("INSERT INTO team_members (id_team, firstname, lastname, nickname, company) VALUES (?, ?, ?, ?, ?)", t.id, firstname, lastname, nickname, company); err != nil { + return Member{}, err + } else if mid, err := res.LastInsertId(); err != nil { + return Member{}, err + } else { + return Member{mid, firstname, lastname, nickname, company}, nil + } +} + +func (t Team) GainMember(m Member) error { + if res, err := DBExec("UPDATE team_members SET id_team = ? WHERE id_member = ?", t.id, m.id); err != nil { + return err + } else if _, err := res.RowsAffected(); err != nil { + return err + } else { + return nil + } +} + +func (m Member) Update() (int64, error) { + if res, err := DBExec("UPDATE team_members SET firstname = ?, lastname = ?, nickname = ?, company = ? WHERE id_member = ?", m.Firstname, m.Lastname, m.Nickname, m.Company, m.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (m Member) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM team_members WHERE id_member = ?", m.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} diff --git a/admin/team.go b/admin/team.go new file mode 100644 index 00000000..4cc13a5b --- /dev/null +++ b/admin/team.go @@ -0,0 +1,69 @@ +package main + +import () + +type Team struct { + id int64 + Name string +} + +func GetTeams() ([]Team, error) { + if rows, err := DBQuery("SELECT id_team, name FROM teams"); err != nil { + return nil, err + } else { + defer rows.Close() + + var teams = make([]Team, 0) + for rows.Next() { + var t Team + if err := rows.Scan(&t.id, &t.Name); err != nil { + return nil, err + } + teams = append(teams, t) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return teams, nil + } +} + +func GetTeam(id int) (Team, error) { + var t Team + if err := DBQueryRow("SELECT id_team, name FROM teams WHERE id_team = ?", id).Scan(&t.id, &t.Name); err != nil { + return t, err + } + + return t, nil +} + +func CreateTeam(name string) (Team, error) { + if res, err := DBExec("INSERT INTO teams (name) VALUES (?)", name); err != nil { + return Team{}, err + } else if tid, err := res.LastInsertId(); err != nil { + return Team{}, err + } else { + return Team{tid, name}, nil + } +} + +func (t Team) Update() (int64, error) { + if res, err := DBExec("UPDATE teams SET name = ? WHERE id_team = ?", t.Name, t.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (t Team) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM teams WHERE id_teams = ?", t.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} diff --git a/admin/theme.go b/admin/theme.go new file mode 100644 index 00000000..dbe15a30 --- /dev/null +++ b/admin/theme.go @@ -0,0 +1,69 @@ +package main + +import () + +type Theme struct { + id int64 + Name string +} + +func GetThemes() ([]Theme, error) { + if rows, err := DBQuery("SELECT id_theme, name FROM themes"); err != nil { + return nil, err + } else { + defer rows.Close() + + var themes = make([]Theme, 0) + for rows.Next() { + var t Theme + if err := rows.Scan(&t.id, &t.Name); err != nil { + return nil, err + } + themes = append(themes, t) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return themes, nil + } +} + +func GetTheme(id int) (Theme, error) { + var t Theme + if err := DBQueryRow("SELECT id_theme, name FROM themes WHERE id_theme=?", id).Scan(&t.id, &t.Name); err != nil { + return t, err + } + + return t, nil +} + +func CreateTheme(name string) (Theme, error) { + if res, err := DBExec("INSERT INTO themes (name) VALUES (?)", name); err != nil { + return Theme{}, err + } else if tid, err := res.LastInsertId(); err != nil { + return Theme{}, err + } else { + return Theme{tid, name}, nil + } +} + +func (t Theme) Update() (int64, error) { + if res, err := DBExec("UPDATE themes SET name = ? WHERE id_team = ?", t.Name, t.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (t Theme) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM themes WHERE id_theme = ?", t.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} From 5a6bac928eef0efcb8375536bfaf0a04ad3e0a54 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 20:08:48 +0100 Subject: [PATCH 0216/2518] Add team listing --- admin/api.go | 2 +- admin/api_team.go | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 admin/api_team.go diff --git a/admin/api.go b/admin/api.go index 0dd72256..647a883c 100644 --- a/admin/api.go +++ b/admin/api.go @@ -14,7 +14,7 @@ type DispatchFunction func([]string, []byte) (interface{}, error) var apiRouting = map[string]*(map[string]DispatchFunction){ "version": &ApiVersionRouting, //"themes": &ApiThemesRouting, - //"teams": &ApiTeamsRouting, + "teams": &ApiTeamsRouting, } func ApiRouting(w http.ResponseWriter, r *http.Request) { diff --git a/admin/api_team.go b/admin/api_team.go new file mode 100644 index 00000000..450d852a --- /dev/null +++ b/admin/api_team.go @@ -0,0 +1,27 @@ +package main + +import ( + "strconv" +) + +var ApiTeamsRouting = map[string]DispatchFunction{ + "GET": list, +} + +func list(args []string, body []byte) (interface{}, error) { + if len(args) == 1 { + // List given team + if tid, err := strconv.Atoi(string(args[0])); err != nil { + return nil, err + } else if team, err := GetTeam(tid); err != nil { + return nil, err + } else { + return team.GetMembers() + } + } else if len(args) == 0 { + // List all teams + return GetTeams() + } else { + return nil, nil + } +} From b958b01635d4fa1a8783041562aeccfc9144c10b Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 20:32:24 +0100 Subject: [PATCH 0217/2518] Implement team creation --- admin/api_team.go | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/admin/api_team.go b/admin/api_team.go index 450d852a..63efa416 100644 --- a/admin/api_team.go +++ b/admin/api_team.go @@ -1,14 +1,16 @@ package main import ( + "encoding/json" "strconv" ) var ApiTeamsRouting = map[string]DispatchFunction{ - "GET": list, + "GET": listTeam, + "POST": creationTeam, } -func list(args []string, body []byte) (interface{}, error) { +func listTeam(args []string, body []byte) (interface{}, error) { if len(args) == 1 { // List given team if tid, err := strconv.Atoi(string(args[0])); err != nil { @@ -25,3 +27,34 @@ func list(args []string, body []byte) (interface{}, error) { return nil, nil } } + +func creationTeam(args []string, body []byte) (interface{}, error) { + if len(args) == 0 { + type UploadedMember struct { + Firstname string + Lastname string + Nickname string + Company string + } + + // Create a new team + var members []UploadedMember + if err := json.Unmarshal(body, &members); err != nil { + return nil, err + } + + if team, err := CreateTeam(""); err != nil { + return nil, err + } else { + for _, member := range members { + if _, err := team.AddMember(member.Firstname, member.Lastname, member.Nickname, member.Company); err != nil { + return nil, err + } + } + + return "Ok", nil + } + } else { + return nil,nil + } +} From 40f7d7a0be2ae1f80a9c45ac585c62ad1a76274f Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 20:47:07 +0100 Subject: [PATCH 0218/2518] Add theme listing --- admin/api.go | 2 +- admin/api_theme.go | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 admin/api_theme.go diff --git a/admin/api.go b/admin/api.go index 647a883c..3e024278 100644 --- a/admin/api.go +++ b/admin/api.go @@ -13,7 +13,7 @@ type DispatchFunction func([]string, []byte) (interface{}, error) var apiRouting = map[string]*(map[string]DispatchFunction){ "version": &ApiVersionRouting, - //"themes": &ApiThemesRouting, + "themes": &ApiThemesRouting, "teams": &ApiTeamsRouting, } diff --git a/admin/api_theme.go b/admin/api_theme.go new file mode 100644 index 00000000..52d8d429 --- /dev/null +++ b/admin/api_theme.go @@ -0,0 +1,25 @@ +package main + +import ( + "strconv" +) + +var ApiThemesRouting = map[string]DispatchFunction{ + "GET": listTheme, +} + +func listTheme(args []string, body []byte) (interface{}, error) { + if len(args) == 1 { + // List given theme + if tid, err := strconv.Atoi(string(args[0])); err != nil { + return nil, err + } else { + return GetTheme(tid) + } + } else if len(args) == 0 { + // List all themes + return GetThemes() + } else { + return nil, nil + } +} From 8cf2a36fe10f7737a0d72ba6bcf17c385e731f31 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 13 Jan 2016 01:12:36 +0100 Subject: [PATCH 0219/2518] Implement team deletion --- admin/api_team.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/admin/api_team.go b/admin/api_team.go index 63efa416..89ec6c24 100644 --- a/admin/api_team.go +++ b/admin/api_team.go @@ -8,6 +8,7 @@ import ( var ApiTeamsRouting = map[string]DispatchFunction{ "GET": listTeam, "POST": creationTeam, + "DELETE": deletionTeam, } func listTeam(args []string, body []byte) (interface{}, error) { @@ -58,3 +59,17 @@ func creationTeam(args []string, body []byte) (interface{}, error) { return nil,nil } } + +func deletionTeam(args []string, body []byte) (interface{}, error) { + if len(args) == 1 { + if tid, err := strconv.Atoi(string(args[0])); err != nil { + return nil, err + } else if team, err := GetTeam(tid); err != nil { + return nil, err + } else { + return team.Delete() + } + } else { + return nil, nil + } +} From e89af34c5c21d738e25014983429f983cb89bcea Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 13 Jan 2016 01:20:21 +0100 Subject: [PATCH 0220/2518] Change internal variable representation vs JSON one --- admin/exercice.go | 30 +++++++++++++++--------------- admin/file.go | 24 ++++++++++++------------ admin/key.go | 22 +++++++++++----------- admin/member.go | 22 +++++++++++----------- admin/team.go | 12 ++++++------ admin/theme.go | 12 ++++++------ 6 files changed, 61 insertions(+), 61 deletions(-) diff --git a/admin/exercice.go b/admin/exercice.go index 988ec192..b7bb1f56 100644 --- a/admin/exercice.go +++ b/admin/exercice.go @@ -5,17 +5,17 @@ import ( ) type Exercice struct { - id int64 - Title string - Statement string - Hint string - depend int64 - Gain int64 - VideoURI string + Id int64 `json:"id"` + Title string `json:"title"` + Statement string `json:"statement"` + Hint string `json:"hint"` + Depend int64 `json:"depend"` + Gain int64 `json:"gain"` + VideoURI string `json:"videoURI"` } func (t Theme) GetExercices() ([]Exercice, error) { - if rows, err := DBQuery("SELECT id_exercice, title, statement, hint, depend, gain, video_uri FROM teams WHERE id_theme = ?", t.id); err != nil { + if rows, err := DBQuery("SELECT id_exercice, title, statement, hint, depend, gain, video_uri FROM teams WHERE id_theme = ?", t.Id); err != nil { return nil, err } else { defer rows.Close() @@ -23,7 +23,7 @@ func (t Theme) GetExercices() ([]Exercice, error) { var exos = make([]Exercice, 0) for rows.Next() { var e Exercice - if err := rows.Scan(&e.id, &e.Title, &e.Statement, &e.Hint, &e.depend, &e.Gain, &e.VideoURI); err != nil { + if err := rows.Scan(&e.Id, &e.Title, &e.Statement, &e.Hint, &e.Depend, &e.Gain, &e.VideoURI); err != nil { return nil, err } exos = append(exos, e) @@ -37,17 +37,17 @@ func (t Theme) GetExercices() ([]Exercice, error) { } func (t Theme) AddExercice(title string, statement string, hint string, depend *Exercice, gain int, videoURI string) (Exercice, error) { - if res, err := DBExec("INSERT INTO exercices (id_theme, title, statement, hint, depend, gain, video_uri) VALUES (?, ?, ?, ?, ?, ?, ?)", t.id, title, statement, hint, depend.id, gain, videoURI); err != nil { + if res, err := DBExec("INSERT INTO exercices (id_theme, title, statement, hint, depend, gain, video_uri) VALUES (?, ?, ?, ?, ?, ?, ?)", t.Id, title, statement, hint, depend.Id, gain, videoURI); err != nil { return Exercice{}, err } else if eid, err := res.LastInsertId(); err != nil { return Exercice{}, err } else { - return Exercice{eid, title, statement, hint, depend.id, int64(gain), videoURI}, nil + return Exercice{eid, title, statement, hint, depend.Id, int64(gain), videoURI}, nil } } func (e Exercice) Update() (int64, error) { - if res, err := DBExec("UPDATE exercices SET title = ?, statement = ?, hint = ?, depend = ?, gain = ?, video_uri = ? WHERE id_exercice = ?", e.Title, e.Statement, e.Hint, e.depend, e.Gain, e.VideoURI, e.id); err != nil { + if res, err := DBExec("UPDATE exercices SET title = ?, statement = ?, hint = ?, depend = ?, gain = ?, video_uri = ? WHERE id_exercice = ?", e.Title, e.Statement, e.Hint, e.Depend, e.Gain, e.VideoURI, e.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -57,7 +57,7 @@ func (e Exercice) Update() (int64, error) { } func (e Exercice) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM exercices WHERE id_exercice = ?", e.id); err != nil { + if res, err := DBExec("DELETE FROM exercices WHERE id_exercice = ?", e.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -67,7 +67,7 @@ func (e Exercice) Delete() (int64, error) { } func (e Exercice) NewTry(t Team) error { - if _, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time) VALUES (?, ?, ?)", e.id, t.id, time.Now()); err != nil { + if _, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time) VALUES (?, ?, ?)", e.Id, t.Id, time.Now()); err != nil { return err } else { return nil @@ -75,7 +75,7 @@ func (e Exercice) NewTry(t Team) error { } func (e Exercice) Solved(t Team) error { - if _, err := DBExec("INSERT INTO exercice_solved (id_exercice, id_team, time) VALUES (?, ?, ?)", e.id, t.id, time.Now()); err != nil { + if _, err := DBExec("INSERT INTO exercice_solved (id_exercice, id_team, time) VALUES (?, ?, ?)", e.Id, t.Id, time.Now()); err != nil { return err } else { return nil diff --git a/admin/file.go b/admin/file.go index 82728ef4..b1255fda 100644 --- a/admin/file.go +++ b/admin/file.go @@ -8,15 +8,15 @@ import ( ) type EFile struct { - id int64 - Path string - id_exercice int64 - Name string - Checksum []byte + Id int64 `json:"id"` + Path string `json:"path"` + IdExercice int64 `json:"idExercice"` + Name string `json:"name"` + Checksum []byte `json:"checksum"` } func (e Exercice) GetFiles() ([]EFile, error) { - if rows, err := DBQuery("SELECT id_file, path, name, sha1 FROM exercice_files WHERE id_exercice = ?", e.id); err != nil { + if rows, err := DBQuery("SELECT id_file, path, name, sha1 FROM exercice_files WHERE id_exercice = ?", e.Id); err != nil { return nil, err } else { defer rows.Close() @@ -24,8 +24,8 @@ func (e Exercice) GetFiles() ([]EFile, error) { var files = make([]EFile, 0) for rows.Next() { var f EFile - f.id_exercice = e.id - if err := rows.Scan(&f.id, &f.Path, &f.Name, &f.Checksum); err != nil { + f.IdExercice = e.Id + if err := rows.Scan(&f.Id, &f.Path, &f.Name, &f.Checksum); err != nil { return nil, err } files = append(files, f) @@ -55,17 +55,17 @@ func (e Exercice) ImportFile(filePath string) (EFile, error) { } func (e Exercice) AddFile(path string, name string, checksum []byte) (EFile, error) { - if res, err := DBExec("INSERT INTO exercice_files (id_exercice, path, name, sha1) VALUES (?, ?, ?, ?)", e.id, path, name, checksum); err != nil { + if res, err := DBExec("INSERT INTO exercice_files (id_exercice, path, name, sha1) VALUES (?, ?, ?, ?)", e.Id, path, name, checksum); err != nil { return EFile{}, err } else if fid, err := res.LastInsertId(); err != nil { return EFile{}, err } else { - return EFile{fid, path, e.id, name, checksum}, nil + return EFile{fid, path, e.Id, name, checksum}, nil } } func (f EFile) Update() (int64, error) { - if res, err := DBExec("UPDATE exercice_files SET id_exercice = ?, path = ?, name = ?, sha1 = ? WHERE id_file = ?", f.id_exercice, f.Path, f.Name, f.Checksum, f.id); err != nil { + if res, err := DBExec("UPDATE exercice_files SET id_exercice = ?, path = ?, name = ?, sha1 = ? WHERE id_file = ?", f.IdExercice, f.Path, f.Name, f.Checksum, f.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -75,7 +75,7 @@ func (f EFile) Update() (int64, error) { } func (f EFile) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM exercice_files WHERE id_file = ?", f.id); err != nil { + if res, err := DBExec("DELETE FROM exercice_files WHERE id_file = ?", f.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/admin/key.go b/admin/key.go index 3052ddb7..a39f2cf6 100644 --- a/admin/key.go +++ b/admin/key.go @@ -5,14 +5,14 @@ import ( ) type Key struct { - id int64 - id_exercice int64 - Type string - Value [64]byte + Id int64 `json:"id"` + IdExercice int64 `json:"idExercice"` + Type string `json:"type"` + Value [64]byte `json:"value"` } func (e Exercice) GetKeys() ([]Key, error) { - if rows, err := DBQuery("SELECT id_key, type, value FROM exercice_keys WHERE id_exercice = ?", e.id); err != nil { + if rows, err := DBQuery("SELECT id_key, type, value FROM exercice_keys WHERE id_exercice = ?", e.Id); err != nil { return nil, err } else { defer rows.Close() @@ -20,8 +20,8 @@ func (e Exercice) GetKeys() ([]Key, error) { var keys = make([]Key, 0) for rows.Next() { var k Key - k.id_exercice = e.id - if err := rows.Scan(&k.id, &k.id_exercice, &k.Type, &k.Value); err != nil { + k.IdExercice = e.Id + if err := rows.Scan(&k.Id, &k.IdExercice, &k.Type, &k.Value); err != nil { return nil, err } keys = append(keys, k) @@ -39,17 +39,17 @@ func (e Exercice) AddRawKey(name string, raw_value string) (Key, error) { } func (e Exercice) AddKey(name string, value [64]byte) (Key, error) { - if res, err := DBExec("INSERT INTO exercice_keys (id_exercice, type, value) VALUES (?, ?, ?)", e.id, name, value); err != nil { + if res, err := DBExec("INSERT INTO exercice_keys (id_exercice, type, value) VALUES (?, ?, ?)", e.Id, name, value); err != nil { return Key{}, err } else if kid, err := res.LastInsertId(); err != nil { return Key{}, err } else { - return Key{kid, e.id, name, value}, nil + return Key{kid, e.Id, name, value}, nil } } func (k Key) Update() (int64, error) { - if res, err := DBExec("UPDATE exercice_keys SET id_exercice = ?, type = ?, value = ? WHERE id_key = ?", k.id_exercice, k.Type, k.Value, k.id); err != nil { + if res, err := DBExec("UPDATE exercice_keys SET id_exercice = ?, type = ?, value = ? WHERE id_key = ?", k.IdExercice, k.Type, k.Value, k.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -59,7 +59,7 @@ func (k Key) Update() (int64, error) { } func (k Key) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM exercice_keys WHERE id_key = ?", k.id); err != nil { + if res, err := DBExec("DELETE FROM exercice_keys WHERE id_key = ?", k.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/admin/member.go b/admin/member.go index 5de67e41..2e17d1d9 100644 --- a/admin/member.go +++ b/admin/member.go @@ -3,15 +3,15 @@ package main import () type Member struct { - id int64 - Firstname string - Lastname string - Nickname string - Company string + Id int64 `json:"id"` + Firstname string `json:"firstname"` + Lastname string `json:"lastname"` + Nickname string `json:"nickname"` + Company string `json:"company"` } func (t Team) GetMembers() ([]Member, error) { - if rows, err := DBQuery("SELECT id_member, firstname, lastname, nickname, company FROM team_members WHERE id_team = ?", t.id); err != nil { + if rows, err := DBQuery("SELECT id_member, firstname, lastname, nickname, company FROM team_members WHERE id_team = ?", t.Id); err != nil { return nil, err } else { defer rows.Close() @@ -19,7 +19,7 @@ func (t Team) GetMembers() ([]Member, error) { var members = make([]Member, 0) for rows.Next() { var m Member - if err := rows.Scan(&m.id, &m.Firstname, &m.Lastname, &m.Nickname, &m.Company); err != nil { + if err := rows.Scan(&m.Id, &m.Firstname, &m.Lastname, &m.Nickname, &m.Company); err != nil { return nil, err } members = append(members, m) @@ -33,7 +33,7 @@ func (t Team) GetMembers() ([]Member, error) { } func (t Team) AddMember(firstname string, lastname string, nickname string, company string) (Member, error) { - if res, err := DBExec("INSERT INTO team_members (id_team, firstname, lastname, nickname, company) VALUES (?, ?, ?, ?, ?)", t.id, firstname, lastname, nickname, company); err != nil { + if res, err := DBExec("INSERT INTO team_members (id_team, firstname, lastname, nickname, company) VALUES (?, ?, ?, ?, ?)", t.Id, firstname, lastname, nickname, company); err != nil { return Member{}, err } else if mid, err := res.LastInsertId(); err != nil { return Member{}, err @@ -43,7 +43,7 @@ func (t Team) AddMember(firstname string, lastname string, nickname string, comp } func (t Team) GainMember(m Member) error { - if res, err := DBExec("UPDATE team_members SET id_team = ? WHERE id_member = ?", t.id, m.id); err != nil { + if res, err := DBExec("UPDATE team_members SET id_team = ? WHERE id_member = ?", t.Id, m.Id); err != nil { return err } else if _, err := res.RowsAffected(); err != nil { return err @@ -53,7 +53,7 @@ func (t Team) GainMember(m Member) error { } func (m Member) Update() (int64, error) { - if res, err := DBExec("UPDATE team_members SET firstname = ?, lastname = ?, nickname = ?, company = ? WHERE id_member = ?", m.Firstname, m.Lastname, m.Nickname, m.Company, m.id); err != nil { + if res, err := DBExec("UPDATE team_members SET firstname = ?, lastname = ?, nickname = ?, company = ? WHERE id_member = ?", m.Firstname, m.Lastname, m.Nickname, m.Company, m.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -63,7 +63,7 @@ func (m Member) Update() (int64, error) { } func (m Member) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM team_members WHERE id_member = ?", m.id); err != nil { + if res, err := DBExec("DELETE FROM team_members WHERE id_member = ?", m.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/admin/team.go b/admin/team.go index 4cc13a5b..f1a42f69 100644 --- a/admin/team.go +++ b/admin/team.go @@ -3,8 +3,8 @@ package main import () type Team struct { - id int64 - Name string + Id int64 `json:"id"` + Name string `json:"name"` } func GetTeams() ([]Team, error) { @@ -16,7 +16,7 @@ func GetTeams() ([]Team, error) { var teams = make([]Team, 0) for rows.Next() { var t Team - if err := rows.Scan(&t.id, &t.Name); err != nil { + if err := rows.Scan(&t.Id, &t.Name); err != nil { return nil, err } teams = append(teams, t) @@ -31,7 +31,7 @@ func GetTeams() ([]Team, error) { func GetTeam(id int) (Team, error) { var t Team - if err := DBQueryRow("SELECT id_team, name FROM teams WHERE id_team = ?", id).Scan(&t.id, &t.Name); err != nil { + if err := DBQueryRow("SELECT id_team, name FROM teams WHERE id_team = ?", id).Scan(&t.Id, &t.Name); err != nil { return t, err } @@ -49,7 +49,7 @@ func CreateTeam(name string) (Team, error) { } func (t Team) Update() (int64, error) { - if res, err := DBExec("UPDATE teams SET name = ? WHERE id_team = ?", t.Name, t.id); err != nil { + if res, err := DBExec("UPDATE teams SET name = ? WHERE id_team = ?", t.Name, t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -59,7 +59,7 @@ func (t Team) Update() (int64, error) { } func (t Team) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM teams WHERE id_teams = ?", t.id); err != nil { + if res, err := DBExec("DELETE FROM team_members WHERE id_team = ?; DELETE FROM teams WHERE id_team = ?", t.Id, t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/admin/theme.go b/admin/theme.go index dbe15a30..5ca0b34e 100644 --- a/admin/theme.go +++ b/admin/theme.go @@ -3,8 +3,8 @@ package main import () type Theme struct { - id int64 - Name string + Id int64 `json:"id"` + Name string `json:"name"` } func GetThemes() ([]Theme, error) { @@ -16,7 +16,7 @@ func GetThemes() ([]Theme, error) { var themes = make([]Theme, 0) for rows.Next() { var t Theme - if err := rows.Scan(&t.id, &t.Name); err != nil { + if err := rows.Scan(&t.Id, &t.Name); err != nil { return nil, err } themes = append(themes, t) @@ -31,7 +31,7 @@ func GetThemes() ([]Theme, error) { func GetTheme(id int) (Theme, error) { var t Theme - if err := DBQueryRow("SELECT id_theme, name FROM themes WHERE id_theme=?", id).Scan(&t.id, &t.Name); err != nil { + if err := DBQueryRow("SELECT id_theme, name FROM themes WHERE id_theme=?", id).Scan(&t.Id, &t.Name); err != nil { return t, err } @@ -49,7 +49,7 @@ func CreateTheme(name string) (Theme, error) { } func (t Theme) Update() (int64, error) { - if res, err := DBExec("UPDATE themes SET name = ? WHERE id_team = ?", t.Name, t.id); err != nil { + if res, err := DBExec("UPDATE themes SET name = ? WHERE id_team = ?", t.Name, t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -59,7 +59,7 @@ func (t Theme) Update() (int64, error) { } func (t Theme) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM themes WHERE id_theme = ?", t.id); err != nil { + if res, err := DBExec("DELETE FROM themes WHERE id_theme = ?", t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err From d635420a9f69bb45dc23c3ba461890b9784b8db5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 13 Jan 2016 01:22:01 +0100 Subject: [PATCH 0221/2518] Add static page routing, place API under /api/ --- admin/api.go | 22 ++++++++++++++-------- admin/main.go | 7 ++++++- admin/static.go | 9 +++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 admin/static.go diff --git a/admin/api.go b/admin/api.go index 3e024278..8ee191f4 100644 --- a/admin/api.go +++ b/admin/api.go @@ -11,18 +11,24 @@ import ( type DispatchFunction func([]string, []byte) (interface{}, error) -var apiRouting = map[string]*(map[string]DispatchFunction){ +var apiRoutes = map[string]*(map[string]DispatchFunction){ "version": &ApiVersionRouting, "themes": &ApiThemesRouting, "teams": &ApiTeamsRouting, } -func ApiRouting(w http.ResponseWriter, r *http.Request) { +type apiRouting struct{} + +func ApiHandler() http.Handler { + return apiRouting{} +} + +func (a apiRouting) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent()) // Extract URL arguments - var sURL = strings.Split(r.URL.Path, "/") - if sURL[len(sURL)-1] == "" && len(sURL) > 2 { + var sURL = strings.Split(r.URL.Path, "/")[1:] + if len(sURL) > 1 && sURL[len(sURL)-1] == "" { // Remove trailing / sURL = sURL[:len(sURL)-1] } @@ -52,12 +58,12 @@ func ApiRouting(w http.ResponseWriter, r *http.Request) { } // Route request - if len(sURL) > 1 { - if h, ok := apiRouting[sURL[1]]; ok { + if len(sURL) > 0 { + if h, ok := apiRoutes[sURL[0]]; ok { if f, ok := (*h)[r.Method]; ok { - ret, err = f(sURL[2:], body) + ret, err = f(sURL[1:], body) } else { - err = errors.New(fmt.Sprintf("Invalid action (%s) provided for %s.", r.Method, sURL[1])) + err = errors.New(fmt.Sprintf("Invalid action (%s) provided for %s.", r.Method, sURL[0])) } } } else { diff --git a/admin/main.go b/admin/main.go index 1979ca64..6277cef4 100644 --- a/admin/main.go +++ b/admin/main.go @@ -34,7 +34,12 @@ func main() { } log.Println("Registering handlers...") - http.HandleFunc("/", ApiRouting) + mux := http.NewServeMux() + mux.Handle("/api/", http.StripPrefix("/api", ApiHandler())) + mux.HandleFunc("/teams", StaticRouting) + mux.HandleFunc("/themes", StaticRouting) + mux.Handle("/", http.FileServer(http.Dir("./static/"))) + http.HandleFunc("/", mux.ServeHTTP) log.Println(fmt.Sprintf("Ready, listening on %s", *bind)) if err := http.ListenAndServe(*bind, nil); err != nil { diff --git a/admin/static.go b/admin/static.go new file mode 100644 index 00000000..f82ab08b --- /dev/null +++ b/admin/static.go @@ -0,0 +1,9 @@ +package main + +import ( + "net/http" +) + +func StaticRouting(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "./static/index.html") +} From 181953a9f03fd54c017c24b991693be3960a2a41 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 13 Jan 2016 01:22:54 +0100 Subject: [PATCH 0222/2518] Work on admin web interface --- admin/static/css/bootstrap.min.css | 6 + admin/static/css/slate.min.css | 11 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 +++++++++++++++++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes admin/static/index.html | 27 ++ admin/static/js/angular-resource.min.js | 14 + admin/static/js/angular-route.min.js | 15 + admin/static/js/angular.min.js | 295 ++++++++++++++++++ admin/static/js/app.js | 33 ++ admin/static/js/bootstrap.min.js | 7 + admin/static/js/jquery.min.js | 5 + admin/static/views/team-list.html | 17 + admin/static/views/team-new.html | 11 + 16 files changed, 729 insertions(+) create mode 100644 admin/static/css/bootstrap.min.css create mode 100644 admin/static/css/slate.min.css create mode 100644 admin/static/fonts/glyphicons-halflings-regular.eot create mode 100644 admin/static/fonts/glyphicons-halflings-regular.svg create mode 100644 admin/static/fonts/glyphicons-halflings-regular.ttf create mode 100644 admin/static/fonts/glyphicons-halflings-regular.woff create mode 100644 admin/static/fonts/glyphicons-halflings-regular.woff2 create mode 100644 admin/static/index.html create mode 100644 admin/static/js/angular-resource.min.js create mode 100644 admin/static/js/angular-route.min.js create mode 100644 admin/static/js/angular.min.js create mode 100644 admin/static/js/app.js create mode 100644 admin/static/js/bootstrap.min.js create mode 100644 admin/static/js/jquery.min.js create mode 100644 admin/static/views/team-list.html create mode 100644 admin/static/views/team-new.html diff --git a/admin/static/css/bootstrap.min.css b/admin/static/css/bootstrap.min.css new file mode 100644 index 00000000..4cf729e4 --- /dev/null +++ b/admin/static/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * 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/admin/static/css/slate.min.css b/admin/static/css/slate.min.css new file mode 100644 index 00000000..af7e2033 --- /dev/null +++ b/admin/static/css/slate.min.css @@ -0,0 +1,11 @@ +/*! + * bootswatch v3.3.6 + * Homepage: http://bootswatch.com + * Copyright 2012-2015 Thomas Park + * Licensed under MIT + * Based on Bootstrap +*//*! + * 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;-ms-text-size-adjust:100%;-webkit-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{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}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{border:0;padding: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-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-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:#c8c8c8;background-color:#272b30}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#ffffff;text-decoration:none}a:hover,a:focus{color:#ffffff;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{padding:4px;line-height:1.42857143;background-color:#1c1e22;border:1px solid #0c0d0e;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #1c1e22}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;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:"Helvetica Neue",Helvetica,Arial,sans-serif;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:#7a8288}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{background-color:#f89406;padding:.2em}.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:#7a8288}.text-primary{color:#7a8288}a.text-primary:hover,a.text-primary:focus{color:#62686d}.text-success{color:#ffffff}a.text-success:hover,a.text-success:focus{color:#e6e6e6}.text-info{color:#ffffff}a.text-info:hover,a.text-info:focus{color:#e6e6e6}.text-warning{color:#ffffff}a.text-warning:hover,a.text-warning:focus{color:#e6e6e6}.text-danger{color:#ffffff}a.text-danger:hover,a.text-danger:focus{color:#e6e6e6}.bg-primary{color:#fff;background-color:#7a8288}a.bg-primary:hover,a.bg-primary:focus{background-color:#62686d}.bg-success{background-color:#62c462}a.bg-success:hover,a.bg-success:focus{background-color:#42b142}.bg-info{background-color:#5bc0de}a.bg-info:hover,a.bg-info:focus{background-color:#31b0d5}.bg-warning{background-color:#f89406}a.bg-warning:hover,a.bg-warning:focus{background-color:#c67605}.bg-danger{background-color:#ee5f5b}a.bg-danger:hover,a.bg-danger:focus{background-color:#e9322d}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #1c1e22}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;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right: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;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #7a8288}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #7a8288}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:#7a8288}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #7a8288;border-left:0;text-align:right}.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:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,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;word-break:break-all;word-wrap:break-word;color:#3a3f44;background-color:#f5f5f5;border:1px solid #cccccc;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{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-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-left:15px;padding-right: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:#2e3338}caption{padding-top:8px;padding-bottom:8px;color:#7a8288;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 #1c1e22}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #1c1e22}.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 #1c1e22}.table .table{background-color:#272b30}.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 #1c1e22}.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 #1c1e22}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#353a41}.table-hover>tbody>tr:hover{background-color:#49515a}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.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:#49515a}.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:#3e444c}.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:#62c462}.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:#4fbd4f}.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:#5bc0de}.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:#46b8da}.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:#f89406}.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:#df8505}.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:#ee5f5b}.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:#ec4844}.table-responsive{overflow-x:auto;min-height:0.01%}@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 #1c1e22}.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{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#c8c8c8;border:0;border-bottom:1px solid #1c1e22}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:9px;font-size:14px;line-height:1.42857143;color:#272b30}.form-control{display:block;width:100%;height:38px;padding:8px 12px;font-size:14px;line-height:1.42857143;color:#272b30;background-color:#ffffff;background-image:none;border:1px solid #cccccc;border-radius:4px;-webkit-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-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,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#7a8288;opacity:1}.form-control:-ms-input-placeholder{color:#7a8288}.form-control::-webkit-input-placeholder{color:#7a8288}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#999999;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:38px}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:54px}}.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-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;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{padding-top:9px;padding-bottom:9px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right: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:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:54px;line-height:54px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:54px;line-height:54px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:54px;min-height:38px;padding:15px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:47.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:38px;height:38px;line-height:38px;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:54px;height:54px;line-height:54px}.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:#ffffff}.has-success .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-success .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#62c462}.has-success .form-control-feedback{color:#ffffff}.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:#ffffff}.has-warning .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-warning .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#f89406}.has-warning .form-control-feedback{color:#ffffff}.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:#ffffff}.has-error .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-error .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#ee5f5b}.has-error .form-control-feedback{color:#ffffff}.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:#ffffff}@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{margin-top:0;margin-bottom:0;padding-top:9px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:29px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:9px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:15px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.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:#ffffff;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#ffffff;background-color:#3a3f44;border-color:#3a3f44}.btn-default:focus,.btn-default.focus{color:#ffffff;background-color:#232628;border-color:#000000}.btn-default:hover{color:#ffffff;background-color:#232628;border-color:#1e2023}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#ffffff;background-color:#232628;border-color:#1e2023}.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:#ffffff;background-color:#121415;border-color:#000000}.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:#3a3f44;border-color:#3a3f44}.btn-default .badge{color:#3a3f44;background-color:#ffffff}.btn-primary{color:#ffffff;background-color:#7a8288;border-color:#7a8288}.btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#62686d;border-color:#3e4245}.btn-primary:hover{color:#ffffff;background-color:#62686d;border-color:#5d6368}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#62686d;border-color:#5d6368}.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:#ffffff;background-color:#51565a;border-color:#3e4245}.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:#7a8288;border-color:#7a8288}.btn-primary .badge{color:#7a8288;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#62c462;border-color:#62c462}.btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#42b142;border-color:#2d792d}.btn-success:hover{color:#ffffff;background-color:#42b142;border-color:#40a940}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#42b142;border-color:#40a940}.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:#ffffff;background-color:#399739;border-color:#2d792d}.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:#62c462;border-color:#62c462}.btn-success .badge{color:#62c462;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#5bc0de;border-color:#5bc0de}.btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#31b0d5;border-color:#1f7e9a}.btn-info:hover{color:#ffffff;background-color:#31b0d5;border-color:#2aabd2}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#31b0d5;border-color:#2aabd2}.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:#ffffff;background-color:#269abc;border-color:#1f7e9a}.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:#5bc0de}.btn-info .badge{color:#5bc0de;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#f89406;border-color:#f89406}.btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#c67605;border-color:#7c4a03}.btn-warning:hover{color:#ffffff;background-color:#c67605;border-color:#bc7005}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#c67605;border-color:#bc7005}.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:#ffffff;background-color:#a36104;border-color:#7c4a03}.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:#f89406;border-color:#f89406}.btn-warning .badge{color:#f89406;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#ee5f5b;border-color:#ee5f5b}.btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#e9322d;border-color:#b71713}.btn-danger:hover{color:#ffffff;background-color:#e9322d;border-color:#e82924}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#e9322d;border-color:#e82924}.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:#ffffff;background-color:#dc1c17;border-color:#b71713}.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:#ee5f5b;border-color:#ee5f5b}.btn-danger .badge{color:#ee5f5b;background-color:#ffffff}.btn-link{color:#ffffff;font-weight:normal;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:#ffffff;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:#7a8288;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:14px 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 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.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-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.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;list-style:none;font-size:14px;text-align:left;background-color:#3a3f44;border:1px solid #272b30;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#272b30}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#c8c8c8;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#ffffff;background-color:#272b30}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#272b30}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#7a8288}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#7a8288;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.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-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-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-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,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-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-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-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;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-left:0;padding-right: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:54px;padding:14px 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:54px;line-height:54px}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:8px 12px;font-size:14px;font-weight:normal;line-height:1;color:#272b30;text-align:center;background-color:#999999;border:1px solid #cccccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:14px 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-bottom-right-radius:0;border-top-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-bottom-left-radius:0;border-top-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{margin-bottom:0;padding-left: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:#3e444c}.nav>li.disabled>a{color:#7a8288}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#7a8288;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#3e444c;border-color:#ffffff}.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 #1c1e22}.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:#1c1e22 #1c1e22 #1c1e22}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#ffffff;background-color:#3e444c;border:1px solid #1c1e22;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.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 #1c1e22}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #1c1e22;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:#272b30}}.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:#ffffff;background-color:transparent}.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{text-align:center;margin-bottom:5px}.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 #1c1e22}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #1c1e22;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:#272b30}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-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{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.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-left:0;padding-right: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;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.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;margin-right:15px;padding:9px 10px;margin-top:8px;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{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-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);margin-top:6px;margin-bottom:6px}@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;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:6px;margin-bottom:6px}.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-left:15px;margin-right: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:#3a3f44;border-color:#2b2e32}.navbar-default .navbar-brand{color:#c8c8c8}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#ffffff;background-color:none}.navbar-default .navbar-text{color:#c8c8c8}.navbar-default .navbar-nav>li>a{color:#c8c8c8}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#ffffff;background-color:#272b2e}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#ffffff;background-color:#272b2e}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#272b2e}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#272b2e}.navbar-default .navbar-toggle .icon-bar{background-color:#c8c8c8}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#2b2e32}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#272b2e;color:#ffffff}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#c8c8c8}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#272b2e}.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:#ffffff;background-color:#272b2e}.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:#cccccc;background-color:transparent}}.navbar-default .navbar-link{color:#c8c8c8}.navbar-default .navbar-link:hover{color:#ffffff}.navbar-default .btn-link{color:#c8c8c8}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#ffffff}.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:#cccccc}.navbar-inverse{background-color:#7a8288;border-color:#62686d}.navbar-inverse .navbar-brand{color:#cccccc}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:none}.navbar-inverse .navbar-text{color:#cccccc}.navbar-inverse .navbar-nav>li>a{color:#cccccc}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:#5d6368}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#5d6368}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#5d6368}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#5d6368}.navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#697075}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#5d6368;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#62686d}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#62686d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#cccccc}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#5d6368}.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:#ffffff;background-color:#5d6368}.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:#cccccc;background-color:transparent}}.navbar-inverse .navbar-link{color:#cccccc}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#cccccc}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.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:#cccccc}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:transparent;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#cccccc}.breadcrumb>.active{color:#7a8288}.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:8px 12px;line-height:1.42857143;text-decoration:none;color:#ffffff;background-color:#3a3f44;border:1px solid rgba(0,0,0,0.6);margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#ffffff;background-color:transparent;border-color:rgba(0,0,0,0.6)}.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:#ffffff;background-color:#232628;border-color:rgba(0,0,0,0.6);cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#7a8288;background-color:#ffffff;border-color:rgba(0,0,0,0.6);cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:14px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-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-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#3a3f44;border:1px solid rgba(0,0,0,0.6);border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:transparent}.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:#7a8288;background-color:#3a3f44;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#3a3f44}.label-default[href]:hover,.label-default[href]:focus{background-color:#232628}.label-primary{background-color:#7a8288}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#62686d}.label-success{background-color:#62c462}.label-success[href]:hover,.label-success[href]:focus{background-color:#42b142}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f89406}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#c67605}.label-danger{background-color:#ee5f5b}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#e9322d}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#7a8288;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:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#ffffff;background-color:#7a8288}.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:#1c1e22}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#050506}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#1c1e22;border:1px solid #0c0d0e;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-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#ffffff}.thumbnail .caption{padding:9px;color:#c8c8c8}.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{background-color:#62c462;border-color:#62bd4f;color:#ffffff}.alert-success hr{border-top-color:#55b142}.alert-success .alert-link{color:#e6e6e6}.alert-info{background-color:#5bc0de;border-color:#3dced8;color:#ffffff}.alert-info hr{border-top-color:#2ac7d2}.alert-info .alert-link{color:#e6e6e6}.alert-warning{background-color:#f89406;border-color:#e96506;color:#ffffff}.alert-warning hr{border-top-color:#d05a05}.alert-warning .alert-link{color:#e6e6e6}.alert-danger{background-color:#ee5f5b;border-color:#ed4d63;color:#ffffff}.alert-danger hr{border-top-color:#ea364f}.alert-danger .alert-link{color:#e6e6e6}@-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{overflow:hidden;height:20px;margin-bottom:20px;background-color:#1c1e22;border-radius:4px;-webkit-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;line-height:20px;color:#ffffff;text-align:center;background-color:#7a8288;-webkit-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-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{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:-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;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:#62c462}.progress-striped .progress-bar-success{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:-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-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{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:-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-bar-warning{background-color:#f89406}.progress-striped .progress-bar-warning{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:-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-bar-danger{background-color:#ee5f5b}.progress-striped .progress-bar-danger{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:-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)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.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{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#32383e;border:1px solid rgba(0,0,0,0.6)}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-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:#c8c8c8}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#ffffff}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#c8c8c8;background-color:#3e444c}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#999999;color:#7a8288;cursor:not-allowed}.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:#7a8288}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#3e444c;border-color:rgba(0,0,0,0.6)}.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:#a2aab4}.list-group-item-success{color:#ffffff;background-color:#62c462}a.list-group-item-success,button.list-group-item-success{color:#ffffff}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:#ffffff;background-color:#4fbd4f}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:#ffffff;border-color:#ffffff}.list-group-item-info{color:#ffffff;background-color:#5bc0de}a.list-group-item-info,button.list-group-item-info{color:#ffffff}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:#ffffff;background-color:#46b8da}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:#ffffff;border-color:#ffffff}.list-group-item-warning{color:#ffffff;background-color:#f89406}a.list-group-item-warning,button.list-group-item-warning{color:#ffffff}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:#ffffff;background-color:#df8505}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:#ffffff;border-color:#ffffff}.list-group-item-danger{color:#ffffff;background-color:#ee5f5b}a.list-group-item-danger,button.list-group-item-danger{color:#ffffff}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:#ffffff;background-color:#ec4844}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:#ffffff;border-color:#ffffff}.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:#2e3338;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-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:#3e444c;border-top:1px solid rgba(0,0,0,0.6);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-right-radius:3px;border-top-left-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-right-radius:0;border-top-left-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-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-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-left-radius:3px;border-bottom-right-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 #1c1e22}.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{border:0;margin-bottom: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 rgba(0,0,0,0.6)}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid rgba(0,0,0,0.6)}.panel-default{border-color:rgba(0,0,0,0.6)}.panel-default>.panel-heading{color:#c8c8c8;background-color:#3e444c;border-color:rgba(0,0,0,0.6)}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-default>.panel-heading .badge{color:#3e444c;background-color:#c8c8c8}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-primary{border-color:rgba(0,0,0,0.6)}.panel-primary>.panel-heading{color:#ffffff;background-color:#7a8288;border-color:rgba(0,0,0,0.6)}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-primary>.panel-heading .badge{color:#7a8288;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-success{border-color:rgba(0,0,0,0.6)}.panel-success>.panel-heading{color:#ffffff;background-color:#62c462;border-color:rgba(0,0,0,0.6)}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-success>.panel-heading .badge{color:#62c462;background-color:#ffffff}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-info{border-color:rgba(0,0,0,0.6)}.panel-info>.panel-heading{color:#ffffff;background-color:#5bc0de;border-color:rgba(0,0,0,0.6)}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-info>.panel-heading .badge{color:#5bc0de;background-color:#ffffff}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-warning{border-color:rgba(0,0,0,0.6)}.panel-warning>.panel-heading{color:#ffffff;background-color:#f89406;border-color:rgba(0,0,0,0.6)}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-warning>.panel-heading .badge{color:#f89406;background-color:#ffffff}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-danger{border-color:rgba(0,0,0,0.6)}.panel-danger>.panel-heading{color:#ffffff;background-color:#ee5f5b;border-color:rgba(0,0,0,0.6)}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-danger>.panel-heading .badge{color:#ee5f5b;background-color:#ffffff}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.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;left:0;bottom:0;height:100%;width: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:#1c1e22;border:1px solid #0c0d0e;border-radius:4px;-webkit-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-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:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.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:#2e3338;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #1c1e22}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{padding:20px;text-align:right;border-top:1px solid #1c1e22}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.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,0.5);box-shadow:0 5px 15px rgba(0,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-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#000000;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:#000000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.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-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#2e3338;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;background-color:#2e3338;border-bottom:1px solid #22262a;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{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#666666;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#2e3338}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#666666;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#2e3338}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#666666;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#2e3338}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#666666;border-left-color:rgba(0,0,0,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#2e3338;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-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{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left: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;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;z-index:5;display:inline-block}.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;line-height:1;font-family:serif}.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%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,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{left:20%;right: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{content:" ";display:table}.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-left:auto;margin-right: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}}.navbar{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)}.navbar-inverse{background-image:-webkit-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-o-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-webkit-gradient(linear, left top, left bottom, from(#8a9196), color-stop(60%, #7a8288), to(#70787d));background-image:linear-gradient(#8a9196, #7a8288 60%, #70787d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8a9196', endColorstr='#ff70787d', GradientType=0);-webkit-filter:none;filter:none}.navbar-inverse .badge{background-color:#5d6368}.navbar-nav>li>a{border-right:1px solid rgba(0,0,0,0.2);border-left:1px solid rgba(255,255,255,0.1)}.navbar-nav>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none;border-left-color:transparent}.navbar .nav .open>a{border-color:transparent}.navbar-nav>li.active>a{border-left-color:transparent}.navbar-form{margin-left:5px;margin-right:5px}.btn,.btn:hover{border-color:rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)}.btn-default{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.btn-default:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none}.btn-primary{background-image:-webkit-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-o-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-webkit-gradient(linear, left top, left bottom, from(#8a9196), color-stop(60%, #7a8288), to(#70787d));background-image:linear-gradient(#8a9196, #7a8288 60%, #70787d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8a9196', endColorstr='#ff70787d', GradientType=0);-webkit-filter:none;filter:none}.btn-primary:hover{background-image:-webkit-linear-gradient(#404448, #4e5458 40%, #585e62);background-image:-o-linear-gradient(#404448, #4e5458 40%, #585e62);background-image:-webkit-gradient(linear, left top, left bottom, from(#404448), color-stop(40%, #4e5458), to(#585e62));background-image:linear-gradient(#404448, #4e5458 40%, #585e62);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff404448', endColorstr='#ff585e62', GradientType=0);-webkit-filter:none;filter:none}.btn-success{background-image:-webkit-linear-gradient(#78cc78, #62c462 60%, #53be53);background-image:-o-linear-gradient(#78cc78, #62c462 60%, #53be53);background-image:-webkit-gradient(linear, left top, left bottom, from(#78cc78), color-stop(60%, #62c462), to(#53be53));background-image:linear-gradient(#78cc78, #62c462 60%, #53be53);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff78cc78', endColorstr='#ff53be53', GradientType=0);-webkit-filter:none;filter:none}.btn-success:hover{background-image:-webkit-linear-gradient(#2f7d2f, #379337 40%, #3da23d);background-image:-o-linear-gradient(#2f7d2f, #379337 40%, #3da23d);background-image:-webkit-gradient(linear, left top, left bottom, from(#2f7d2f), color-stop(40%, #379337), to(#3da23d));background-image:linear-gradient(#2f7d2f, #379337 40%, #3da23d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f7d2f', endColorstr='#ff3da23d', GradientType=0);-webkit-filter:none;filter:none}.btn-info{background-image:-webkit-linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-image:-o-linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-image:-webkit-gradient(linear, left top, left bottom, from(#74cae3), color-stop(60%, #5bc0de), to(#4ab9db));background-image:linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff74cae3', endColorstr='#ff4ab9db', GradientType=0);-webkit-filter:none;filter:none}.btn-info:hover{background-image:-webkit-linear-gradient(#20829f, #2596b8 40%, #28a4c9);background-image:-o-linear-gradient(#20829f, #2596b8 40%, #28a4c9);background-image:-webkit-gradient(linear, left top, left bottom, from(#20829f), color-stop(40%, #2596b8), to(#28a4c9));background-image:linear-gradient(#20829f, #2596b8 40%, #28a4c9);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff20829f', endColorstr='#ff28a4c9', GradientType=0);-webkit-filter:none;filter:none}.btn-warning{background-image:-webkit-linear-gradient(#faa123, #f89406 60%, #e48806);background-image:-o-linear-gradient(#faa123, #f89406 60%, #e48806);background-image:-webkit-gradient(linear, left top, left bottom, from(#faa123), color-stop(60%, #f89406), to(#e48806));background-image:linear-gradient(#faa123, #f89406 60%, #e48806);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffaa123', endColorstr='#ffe48806', GradientType=0);-webkit-filter:none;filter:none}.btn-warning:hover{background-image:-webkit-linear-gradient(#804d03, #9e5f04 40%, #b26a04);background-image:-o-linear-gradient(#804d03, #9e5f04 40%, #b26a04);background-image:-webkit-gradient(linear, left top, left bottom, from(#804d03), color-stop(40%, #9e5f04), to(#b26a04));background-image:linear-gradient(#804d03, #9e5f04 40%, #b26a04);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff804d03', endColorstr='#ffb26a04', GradientType=0);-webkit-filter:none;filter:none}.btn-danger{background-image:-webkit-linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-image:-o-linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-image:-webkit-gradient(linear, left top, left bottom, from(#f17a77), color-stop(60%, #ee5f5b), to(#ec4d49));background-image:linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff17a77', endColorstr='#ffec4d49', GradientType=0);-webkit-filter:none;filter:none}.btn-danger:hover{background-image:-webkit-linear-gradient(#bb1813, #d71c16 40%, #e7201a);background-image:-o-linear-gradient(#bb1813, #d71c16 40%, #e7201a);background-image:-webkit-gradient(linear, left top, left bottom, from(#bb1813), color-stop(40%, #d71c16), to(#e7201a));background-image:linear-gradient(#bb1813, #d71c16 40%, #e7201a);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffbb1813', endColorstr='#ffe7201a', GradientType=0);-webkit-filter:none;filter:none}.btn-link,.btn-link:hover{border-color:transparent}h1,h2,h3,h4,h5,h6{text-shadow:-1px -1px 0 rgba(0,0,0,0.3)}.text-primary,.text-primary:hover{color:#7a8288}.text-success,.text-success:hover{color:#62c462}.text-danger,.text-danger:hover{color:#ee5f5b}.text-warning,.text-warning:hover{color:#f89406}.text-info,.text-info:hover{color:#5bc0de}.table .success,.table .warning,.table .danger,.table .info{color:#fff}.table-bordered tbody tr.success td,.table-bordered tbody tr.warning td,.table-bordered tbody tr.danger td,.table-bordered tbody tr.success:hover td,.table-bordered tbody tr.warning:hover td,.table-bordered tbody tr.danger:hover td{border-color:#1c1e22}.table-responsive>.table{background-color:#2e3338}input,textarea{color:#272b30}.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,.has-warning .form-control-feedback{color:#f89406}.has-warning .form-control,.has-warning .form-control:focus{border-color:#f89406}.has-warning .input-group-addon{background-color:#272b30;border:none}.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,.has-error .form-control-feedback{color:#ee5f5b}.has-error .form-control,.has-error .form-control:focus{border-color:#ee5f5b}.has-error .input-group-addon{background-color:#272b30;border:none}.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,.has-success .form-control-feedback{color:#62c462}.has-success .form-control,.has-success .form-control:focus{border-color:#62c462}.has-success .input-group-addon{background-color:#272b30;border:none}legend{color:#fff}.input-group-addon{border-color:rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3);background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;color:#ffffff}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{border-color:rgba(0,0,0,0.6)}.nav-pills>li>a{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)}.nav-pills>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6)}.nav-pills>li.active>a,.nav-pills>li.active>a:hover{background-color:none;background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6)}.nav-pills>li.disabled>a,.nav-pills>li.disabled>a:hover{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.pagination>li>a,.pagination>li>span{text-shadow:1px 1px 1px rgba(0,0,0,0.3);background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.pagination>li>a:hover,.pagination>li>span:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none}.pagination>li.active>a,.pagination>li.active>span{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none}.pagination>li.disabled>a,.pagination>li.disabled>a:hover,.pagination>li.disabled>span,.pagination>li.disabled>span:hover{background-color:transparent;background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.pager>li>a{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;text-shadow:1px 1px 1px rgba(0,0,0,0.3)}.pager>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none}.pager>li.disabled>a,.pager>li.disabled>a:hover{background-color:transparent;background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.breadcrumb{border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3);background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert .close{color:#000000;text-decoration:none}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#0c0d0e}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{border-color:rgba(0,0,0,0.6)}a.list-group-item-success.active{background-color:#62c462}a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{background-color:#4fbd4f}a.list-group-item-warning.active{background-color:#f89406}a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{background-color:#df8505}a.list-group-item-danger.active{background-color:#ee5f5b}a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{background-color:#ec4844}.jumbotron{border:1px solid rgba(0,0,0,0.6)}.panel-primary .panel-heading,.panel-success .panel-heading,.panel-danger .panel-heading,.panel-warning .panel-heading,.panel-info .panel-heading{border-color:#000} \ No newline at end of file diff --git a/admin/static/fonts/glyphicons-halflings-regular.eot b/admin/static/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..b93a4953fff68df523aa7656497ee339d6026d64 GIT binary patch literal 20127 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/admin/static/fonts/glyphicons-halflings-regular.ttf b/admin/static/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 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 G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/admin/static/fonts/glyphicons-halflings-regular.woff2 b/admin/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 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 literal 0 HcmV?d00001 diff --git a/admin/static/index.html b/admin/static/index.html new file mode 100644 index 00000000..96ef0a41 --- /dev/null +++ b/admin/static/index.html @@ -0,0 +1,27 @@ + + + + + Challenge Forensic FIC 2016 - Administration + + + + +
    + +
    +
    +
    +
    + + + + + + + + + diff --git a/admin/static/js/angular-resource.min.js b/admin/static/js/angular-resource.min.js new file mode 100644 index 00000000..c3fb7aab --- /dev/null +++ b/admin/static/js/angular-resource.min.js @@ -0,0 +1,14 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(I,f,C){'use strict';function D(t,e){e=e||{};f.forEach(e,function(f,k){delete e[k]});for(var k in t)!t.hasOwnProperty(k)||"$"===k.charAt(0)&&"$"===k.charAt(1)||(e[k]=t[k]);return e}var y=f.$$minErr("$resource"),B=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;f.module("ngResource",["ng"]).provider("$resource",function(){var t=/^https?:\/\/[^\/]*/,e=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}}; +this.$get=["$http","$q",function(k,F){function w(f,g){this.template=f;this.defaults=r({},e.defaults,g);this.urlParams={}}function z(l,g,s,h){function c(a,q){var c={};q=r({},g,q);u(q,function(b,q){x(b)&&(b=b());var m;if(b&&b.charAt&&"@"==b.charAt(0)){m=a;var d=b.substr(1);if(null==d||""===d||"hasOwnProperty"===d||!B.test("."+d))throw y("badmember",d);for(var d=d.split("."),n=0,g=d.length;n").append(a).html();try{return a[0].nodeType===Na?F(d):d.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+F(b)})}catch(c){return F(d)}}function wc(a){try{return decodeURIComponent(a)}catch(b){}} +function xc(a){var b={};n((a||"").split("&"),function(a){var c,e,f;a&&(e=a=a.replace(/\+/g,"%20"),c=a.indexOf("="),-1!==c&&(e=a.substring(0,c),f=a.substring(c+1)),e=wc(e),y(e)&&(f=y(f)?wc(f):!0,qa.call(b,e)?I(b[e])?b[e].push(f):b[e]=[b[e],f]:b[e]=f))});return b}function Qb(a){var b=[];n(a,function(a,c){I(a)?n(a,function(a){b.push(ja(c,!0)+(!0===a?"":"="+ja(a,!0)))}):b.push(ja(c,!0)+(!0===a?"":"="+ja(a,!0)))});return b.length?b.join("&"):""}function ob(a){return ja(a,!0).replace(/%26/gi,"&").replace(/%3D/gi, +"=").replace(/%2B/gi,"+")}function ja(a,b){return encodeURIComponent(a).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,b?"%20":"+")}function Yd(a,b){var d,c,e=Oa.length;for(c=0;c/,">"));}b=b||[];b.unshift(["$provide",function(b){b.value("$rootElement",a)}]);d.debugInfoEnabled&&b.push(["$compileProvider",function(a){a.debugInfoEnabled(!0)}]);b.unshift("ng");c=eb(b,d.strictDi);c.invoke(["$rootScope", +"$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},e=/^NG_ENABLE_DEBUG_INFO!/,f=/^NG_DEFER_BOOTSTRAP!/;S&&e.test(S.name)&&(d.debugInfoEnabled=!0,S.name=S.name.replace(e,""));if(S&&!f.test(S.name))return c();S.name=S.name.replace(f,"");fa.resumeBootstrap=function(a){n(a,function(a){b.push(a)});return c()};z(fa.resumeDeferredBootstrap)&&fa.resumeDeferredBootstrap()}function $d(){S.name="NG_ENABLE_DEBUG_INFO!"+S.name;S.location.reload()} +function ae(a){a=fa.element(a).injector();if(!a)throw Aa("test");return a.get("$$testability")}function zc(a,b){b=b||"_";return a.replace(be,function(a,c){return(c?b:"")+a.toLowerCase()})}function ce(){var a;if(!Ac){var b=pb();(oa=q(b)?S.jQuery:b?S[b]:u)&&oa.fn.on?(B=oa,M(oa.fn,{scope:Pa.scope,isolateScope:Pa.isolateScope,controller:Pa.controller,injector:Pa.injector,inheritedData:Pa.inheritedData}),a=oa.cleanData,oa.cleanData=function(b){var c;if(Rb)Rb=!1;else for(var e=0,f;null!=(f=b[e]);e++)(c= +oa._data(f,"events"))&&c.$destroy&&oa(f).triggerHandler("$destroy");a(b)}):B=N;fa.element=B;Ac=!0}}function qb(a,b,d){if(!a)throw Aa("areq",b||"?",d||"required");return a}function Qa(a,b,d){d&&I(a)&&(a=a[a.length-1]);qb(z(a),b,"not a function, got "+(a&&"object"===typeof a?a.constructor.name||"Object":typeof a));return a}function Ra(a,b){if("hasOwnProperty"===a)throw Aa("badname",b);}function Bc(a,b,d){if(!b)return a;b=b.split(".");for(var c,e=a,f=b.length,g=0;g")+c[2];for(c=c[0];c--;)d=d.lastChild;f=cb(f,d.childNodes);d=e.firstChild;d.textContent=""}else f.push(b.createTextNode(a));e.textContent="";e.innerHTML="";n(f,function(a){e.appendChild(a)});return e}function N(a){if(a instanceof N)return a;var b;E(a)&&(a=U(a), +b=!0);if(!(this instanceof N)){if(b&&"<"!=a.charAt(0))throw Ub("nosel");return new N(a)}if(b){b=X;var d;a=(d=Ef.exec(a))?[b.createElement(d[1])]:(d=Lc(a,b))?d.childNodes:[]}Mc(this,a)}function Vb(a){return a.cloneNode(!0)}function ub(a,b){b||vb(a);if(a.querySelectorAll)for(var d=a.querySelectorAll("*"),c=0,e=d.length;cl&&this.remove(t.key);return b}},get:function(a){if(l").parent()[0])});var f=O(a,b,a,c,d,e);K.$$addScopeClass(a);var g=null;return function(b,c,d){qb(b,"scope");e&&e.needsNewScope&&(b=b.$parent.$new());d=d||{};var h=d.parentBoundTranscludeFn,k=d.transcludeControllers;d=d.futureParentElement;h&&h.$$boundTransclude&&(h=h.$$boundTransclude);g||(g=(d= +d&&d[0])?"foreignobject"!==ta(d)&&d.toString().match(/SVG/)?"svg":"html":"html");d="html"!==g?B(Yb(g,B("
    ").append(a).html())):c?Pa.clone.call(a):a;if(k)for(var l in k)d.data("$"+l+"Controller",k[l].instance);K.$$addScopeInfo(d,b);c&&c(d,b);f&&f(b,d,d,h);return d}}function O(a,b,c,d,e,f){function g(a,c,d,e){var f,k,l,m,t,w,D;if(p)for(D=Array(c.length),m=0;mq.priority)break;if(P=q.scope)q.templateUrl||(H(P)?(Ua("new/isolated scope",O||R,q,Z),O=q):Ua("new/isolated scope",O,q,Z)),R=R||q;x=q.name;!q.templateUrl&&q.controller&&(P=q.controller,T=T||$(),Ua("'"+x+"' controller",T[x],q,Z),T[x]=q);if(P=q.transclude)ga=!0,q.$$tlb||(Ua("transclusion",n,q,Z),n=q),"element"==P?(aa=!0,A=q.priority,P=Z,Z=d.$$element=B(X.createComment(" "+x+": "+d[x]+" ")),b=Z[0],Y(f,ra.call(P,0), +b),Ia=K(P,e,A,g&&g.name,{nonTlbTranscludeDirective:n})):(P=B(Vb(b)).contents(),Z.empty(),Ia=K(P,e,u,u,{needsNewScope:q.$$isolateScope||q.$$newScope}));if(q.template)if(L=!0,Ua("template",J,q,Z),J=q,P=z(q.template)?q.template(Z,d):q.template,P=ja(P),q.replace){g=q;P=Tb.test(P)?Xc(Yb(q.templateNamespace,U(P))):[];b=P[0];if(1!=P.length||1!==b.nodeType)throw ha("tplrt",x,"");Y(f,Z,b);P={$attr:{}};var Wc=V(b,[],P),W=a.splice(F+1,a.length-(F+1));(O||R)&&y(Wc,O,R);a=a.concat(Wc).concat(W);S(d,P);M=a.length}else Z.html(P); +if(q.templateUrl)L=!0,Ua("template",J,q,Z),J=q,q.replace&&(g=q),D=Of(a.splice(F,a.length-F),Z,d,f,ga&&Ia,h,l,{controllerDirectives:T,newScopeDirective:R!==q&&R,newIsolateScopeDirective:O,templateDirective:J,nonTlbTranscludeDirective:n}),M=a.length;else if(q.compile)try{G=q.compile(Z,d,Ia),z(G)?t(null,G,N,Q):G&&t(G.pre,G.post,N,Q)}catch(da){c(da,ua(Z))}q.terminal&&(D.terminal=!0,A=Math.max(A,q.priority))}D.scope=R&&!0===R.scope;D.transcludeOnThisElement=ga;D.templateOnThisElement=L;D.transclude=Ia; +m.hasElementTranscludeDirective=aa;return D}function y(a,b,c){for(var d=0,e=a.length;dm.priority)&&-1!=m.restrict.indexOf(f)&&(k&&(m=Ob(m,{$$start:k,$$end:l})),b.push(m),h=m)}catch(D){c(D)}}return h}function G(b){if(e.hasOwnProperty(b))for(var c=a.get(b+"Directive"),d=0,f=c.length;d"+b+"";return c.childNodes[0].childNodes;default:return b}}function Q(a,b){if("srcdoc"==b)return L.HTML;var c=ta(a);if("xlinkHref"==b||"form"==c&&"action"==b||"img"!=c&&("src"==b||"ngSrc"==b))return L.RESOURCE_URL}function W(a,c,d,e,f){var g=Q(a,e);f=h[e]||f;var k=b(d,!0,g,f);if(k){if("multiple"===e&&"select"===ta(a))throw ha("selmulti",ua(a));c.push({priority:100,compile:function(){return{pre:function(a,c,h){c=h.$$observers||(h.$$observers=$());if(l.test(e))throw ha("nodomevents"); +var m=h[e];m!==d&&(k=m&&b(m,!0,g,f),d=m);k&&(h[e]=k(a),(c[e]||(c[e]=[])).$$inter=!0,(h.$$observers&&h.$$observers[e].$$scope||a).$watch(k,function(a,b){"class"===e&&a!=b?h.$updateClass(a,b):h.$set(e,a)}))}}}})}}function Y(a,b,c){var d=b[0],e=b.length,f=d.parentNode,g,h;if(a)for(g=0,h=a.length;g=b)return a;for(;b--;)8===a[b].nodeType&&Pf.call(a,b,1);return a}function Xe(){var a={},b=!1;this.register=function(b,c){Ra(b,"controller");H(b)?M(a,b):a[b]=c};this.allowGlobals=function(){b=!0};this.$get=["$injector","$window",function(d,c){function e(a,b,c,d){if(!a||!H(a.$scope))throw G("$controller")("noscp", +d,b);a.$scope[b]=c}return function(f,g,h,k){var l,m,r;h=!0===h;k&&E(k)&&(r=k);if(E(f)){k=f.match(Uc);if(!k)throw Qf("ctrlfmt",f);m=k[1];r=r||k[3];f=a.hasOwnProperty(m)?a[m]:Bc(g.$scope,m,!0)||(b?Bc(c,m,!0):u);Qa(f,m,!0)}if(h)return h=(I(f)?f[f.length-1]:f).prototype,l=Object.create(h||null),r&&e(g,r,l,m||f.name),M(function(){var a=d.invoke(f,l,g,m);a!==l&&(H(a)||z(a))&&(l=a,r&&e(g,r,l,m||f.name));return l},{instance:l,identifier:r});l=d.instantiate(f,g,m);r&&e(g,r,l,m||f.name);return l}}]}function Ye(){this.$get= +["$window",function(a){return B(a.document)}]}function Ze(){this.$get=["$log",function(a){return function(b,d){a.error.apply(a,arguments)}}]}function Zb(a){return H(a)?da(a)?a.toISOString():db(a):a}function df(){this.$get=function(){return function(a){if(!a)return"";var b=[];oc(a,function(a,c){null===a||q(a)||(I(a)?n(a,function(a,d){b.push(ja(c)+"="+ja(Zb(a)))}):b.push(ja(c)+"="+ja(Zb(a))))});return b.join("&")}}}function ef(){this.$get=function(){return function(a){function b(a,e,f){null===a||q(a)|| +(I(a)?n(a,function(a,c){b(a,e+"["+(H(a)?c:"")+"]")}):H(a)&&!da(a)?oc(a,function(a,c){b(a,e+(f?"":"[")+c+(f?"":"]"))}):d.push(ja(e)+"="+ja(Zb(a))))}if(!a)return"";var d=[];b(a,"",!0);return d.join("&")}}}function $b(a,b){if(E(a)){var d=a.replace(Rf,"").trim();if(d){var c=b("Content-Type");(c=c&&0===c.indexOf($c))||(c=(c=d.match(Sf))&&Tf[c[0]].test(d));c&&(a=uc(d))}}return a}function ad(a){var b=$(),d;E(a)?n(a.split("\n"),function(a){d=a.indexOf(":");var e=F(U(a.substr(0,d)));a=U(a.substr(d+1));e&& +(b[e]=b[e]?b[e]+", "+a:a)}):H(a)&&n(a,function(a,d){var f=F(d),g=U(a);f&&(b[f]=b[f]?b[f]+", "+g:g)});return b}function bd(a){var b;return function(d){b||(b=ad(a));return d?(d=b[F(d)],void 0===d&&(d=null),d):b}}function cd(a,b,d,c){if(z(c))return c(a,b,d);n(c,function(c){a=c(a,b,d)});return a}function cf(){var a=this.defaults={transformResponse:[$b],transformRequest:[function(a){return H(a)&&"[object File]"!==sa.call(a)&&"[object Blob]"!==sa.call(a)&&"[object FormData]"!==sa.call(a)?db(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"}, +post:ia(ac),put:ia(ac),patch:ia(ac)},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",paramSerializer:"$httpParamSerializer"},b=!1;this.useApplyAsync=function(a){return y(a)?(b=!!a,this):b};var d=!0;this.useLegacyPromiseExtensions=function(a){return y(a)?(d=!!a,this):d};var c=this.interceptors=[];this.$get=["$httpBackend","$$cookieReader","$cacheFactory","$rootScope","$q","$injector",function(e,f,g,h,k,l){function m(b){function c(a){var b=M({},a);b.data=cd(a.data,a.headers,a.status,f.transformResponse); +a=a.status;return 200<=a&&300>a?b:k.reject(b)}function e(a,b){var c,d={};n(a,function(a,e){z(a)?(c=a(b),null!=c&&(d[e]=c)):d[e]=a});return d}if(!fa.isObject(b))throw G("$http")("badreq",b);var f=M({method:"get",transformRequest:a.transformRequest,transformResponse:a.transformResponse,paramSerializer:a.paramSerializer},b);f.headers=function(b){var c=a.headers,d=M({},b.headers),f,g,h,c=M({},c.common,c[F(b.method)]);a:for(f in c){g=F(f);for(h in d)if(F(h)===g)continue a;d[f]=c[f]}return e(d,ia(b))}(b); +f.method=sb(f.method);f.paramSerializer=E(f.paramSerializer)?l.get(f.paramSerializer):f.paramSerializer;var g=[function(b){var d=b.headers,e=cd(b.data,bd(d),u,b.transformRequest);q(e)&&n(d,function(a,b){"content-type"===F(b)&&delete d[b]});q(b.withCredentials)&&!q(a.withCredentials)&&(b.withCredentials=a.withCredentials);return r(b,e).then(c,c)},u],h=k.when(f);for(n(v,function(a){(a.request||a.requestError)&&g.unshift(a.request,a.requestError);(a.response||a.responseError)&&g.push(a.response,a.responseError)});g.length;){b= +g.shift();var m=g.shift(),h=h.then(b,m)}d?(h.success=function(a){Qa(a,"fn");h.then(function(b){a(b.data,b.status,b.headers,f)});return h},h.error=function(a){Qa(a,"fn");h.then(null,function(b){a(b.data,b.status,b.headers,f)});return h}):(h.success=dd("success"),h.error=dd("error"));return h}function r(c,d){function g(a,c,d,e){function f(){l(c,a,d,e)}J&&(200<=a&&300>a?J.put(R,[a,c,ad(d),e]):J.remove(R));b?h.$applyAsync(f):(f(),h.$$phase||h.$apply())}function l(a,b,d,e){b=-1<=b?b:0;(200<=b&&300>b?n.resolve: +n.reject)({data:a,status:b,headers:bd(d),config:c,statusText:e})}function r(a){l(a.data,a.status,ia(a.headers()),a.statusText)}function v(){var a=m.pendingRequests.indexOf(c);-1!==a&&m.pendingRequests.splice(a,1)}var n=k.defer(),D=n.promise,J,K,O=c.headers,R=t(c.url,c.paramSerializer(c.params));m.pendingRequests.push(c);D.then(v,v);!c.cache&&!a.cache||!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method||(J=H(c.cache)?c.cache:H(a.cache)?a.cache:A);J&&(K=J.get(R),y(K)?K&&z(K.then)?K.then(r,r):I(K)?l(K[1], +K[0],ia(K[2]),K[3]):l(K,200,{},"OK"):J.put(R,D));q(K)&&((K=ed(c.url)?f()[c.xsrfCookieName||a.xsrfCookieName]:u)&&(O[c.xsrfHeaderName||a.xsrfHeaderName]=K),e(c.method,R,d,g,O,c.timeout,c.withCredentials,c.responseType));return D}function t(a,b){0=k&&(p.resolve(v),A(C.$$intervalId),delete f[C.$$intervalId]);n||a.$apply()},h);f[C.$$intervalId]=p;return C}var f={};e.cancel=function(a){return a&&a.$$intervalId in f?(f[a.$$intervalId].reject("canceled"),b.clearInterval(a.$$intervalId),delete f[a.$$intervalId],!0):!1};return e}]}function bc(a){a=a.split("/");for(var b=a.length;b--;)a[b]=ob(a[b]);return a.join("/")}function fd(a,b){var d=wa(a);b.$$protocol=d.protocol;b.$$host=d.hostname;b.$$port=ea(d.port)||Vf[d.protocol]|| +null}function gd(a,b){var d="/"!==a.charAt(0);d&&(a="/"+a);var c=wa(a);b.$$path=decodeURIComponent(d&&"/"===c.pathname.charAt(0)?c.pathname.substring(1):c.pathname);b.$$search=xc(c.search);b.$$hash=decodeURIComponent(c.hash);b.$$path&&"/"!=b.$$path.charAt(0)&&(b.$$path="/"+b.$$path)}function pa(a,b){if(0===b.indexOf(a))return b.substr(a.length)}function Fa(a){var b=a.indexOf("#");return-1==b?a:a.substr(0,b)}function ib(a){return a.replace(/(#.+)|#$/,"$1")}function cc(a,b,d){this.$$html5=!0;d=d||""; +fd(a,this);this.$$parse=function(a){var d=pa(b,a);if(!E(d))throw Db("ipthprfx",a,b);gd(d,this);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Qb(this.$$search),d=this.$$hash?"#"+ob(this.$$hash):"";this.$$url=bc(this.$$path)+(a?"?"+a:"")+d;this.$$absUrl=b+this.$$url.substr(1)};this.$$parseLinkUrl=function(c,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;y(f=pa(a,c))?(g=f,g=y(f=pa(d,f))?b+(pa("/",f)||f):a+g):y(f=pa(b,c))?g=b+f:b==c+"/"&&(g=b);g&&this.$$parse(g); +return!!g}}function dc(a,b,d){fd(a,this);this.$$parse=function(c){var e=pa(a,c)||pa(b,c),f;q(e)||"#"!==e.charAt(0)?this.$$html5?f=e:(f="",q(e)&&(a=c,this.replace())):(f=pa(d,e),q(f)&&(f=e));gd(f,this);c=this.$$path;var e=a,g=/^\/[A-Z]:(\/.*)/;0===f.indexOf(e)&&(f=f.replace(e,""));g.exec(f)||(c=(f=g.exec(c))?f[1]:c);this.$$path=c;this.$$compose()};this.$$compose=function(){var b=Qb(this.$$search),e=this.$$hash?"#"+ob(this.$$hash):"";this.$$url=bc(this.$$path)+(b?"?"+b:"")+e;this.$$absUrl=a+(this.$$url? +d+this.$$url:"")};this.$$parseLinkUrl=function(b,d){return Fa(a)==Fa(b)?(this.$$parse(b),!0):!1}}function hd(a,b,d){this.$$html5=!0;dc.apply(this,arguments);this.$$parseLinkUrl=function(c,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;a==Fa(c)?f=c:(g=pa(b,c))?f=a+d+g:b===c+"/"&&(f=b);f&&this.$$parse(f);return!!f};this.$$compose=function(){var b=Qb(this.$$search),e=this.$$hash?"#"+ob(this.$$hash):"";this.$$url=bc(this.$$path)+(b?"?"+b:"")+e;this.$$absUrl=a+d+this.$$url}}function Eb(a){return function(){return this[a]}} +function id(a,b){return function(d){if(q(d))return this[a];this[a]=b(d);this.$$compose();return this}}function hf(){var a="",b={enabled:!1,requireBase:!0,rewriteLinks:!0};this.hashPrefix=function(b){return y(b)?(a=b,this):a};this.html5Mode=function(a){return $a(a)?(b.enabled=a,this):H(a)?($a(a.enabled)&&(b.enabled=a.enabled),$a(a.requireBase)&&(b.requireBase=a.requireBase),$a(a.rewriteLinks)&&(b.rewriteLinks=a.rewriteLinks),this):b};this.$get=["$rootScope","$browser","$sniffer","$rootElement","$window", +function(d,c,e,f,g){function h(a,b,d){var e=l.url(),f=l.$$state;try{c.url(a,b,d),l.$$state=c.state()}catch(g){throw l.url(e),l.$$state=f,g;}}function k(a,b){d.$broadcast("$locationChangeSuccess",l.absUrl(),a,l.$$state,b)}var l,m;m=c.baseHref();var r=c.url(),t;if(b.enabled){if(!m&&b.requireBase)throw Db("nobase");t=r.substring(0,r.indexOf("/",r.indexOf("//")+2))+(m||"/");m=e.history?cc:hd}else t=Fa(r),m=dc;var A=t.substr(0,Fa(t).lastIndexOf("/")+1);l=new m(t,A,"#"+a);l.$$parseLinkUrl(r,r);l.$$state= +c.state();var v=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(b.rewriteLinks&&!a.ctrlKey&&!a.metaKey&&!a.shiftKey&&2!=a.which&&2!=a.button){for(var e=B(a.target);"a"!==ta(e[0]);)if(e[0]===f[0]||!(e=e.parent())[0])return;var h=e.prop("href"),k=e.attr("href")||e.attr("xlink:href");H(h)&&"[object SVGAnimatedString]"===h.toString()&&(h=wa(h.animVal).href);v.test(h)||!h||e.attr("target")||a.isDefaultPrevented()||!l.$$parseLinkUrl(h,k)||(a.preventDefault(),l.absUrl()!=c.url()&&(d.$apply(),g.angular["ff-684208-preventDefault"]= +!0))}});ib(l.absUrl())!=ib(r)&&c.url(l.absUrl(),!0);var n=!0;c.onUrlChange(function(a,b){q(pa(A,a))?g.location.href=a:(d.$evalAsync(function(){var c=l.absUrl(),e=l.$$state,f;a=ib(a);l.$$parse(a);l.$$state=b;f=d.$broadcast("$locationChangeStart",a,c,b,e).defaultPrevented;l.absUrl()===a&&(f?(l.$$parse(c),l.$$state=e,h(c,!1,e)):(n=!1,k(c,e)))}),d.$$phase||d.$digest())});d.$watch(function(){var a=ib(c.url()),b=ib(l.absUrl()),f=c.state(),g=l.$$replace,m=a!==b||l.$$html5&&e.history&&f!==l.$$state;if(n|| +m)n=!1,d.$evalAsync(function(){var b=l.absUrl(),c=d.$broadcast("$locationChangeStart",b,a,l.$$state,f).defaultPrevented;l.absUrl()===b&&(c?(l.$$parse(a),l.$$state=f):(m&&h(b,g,f===l.$$state?null:l.$$state),k(a,f)))});l.$$replace=!1});return l}]}function jf(){var a=!0,b=this;this.debugEnabled=function(b){return y(b)?(a=b,this):a};this.$get=["$window",function(d){function c(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&& +(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=d.console||{},e=b[a]||b.log||x;a=!1;try{a=!!e.apply}catch(k){}return a?function(){var a=[];n(arguments,function(b){a.push(c(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){a&&c.apply(b,arguments)}}()}}]}function Va(a,b){if("__defineGetter__"===a||"__defineSetter__"===a||"__lookupGetter__"===a||"__lookupSetter__"=== +a||"__proto__"===a)throw ba("isecfld",b);return a}function jd(a,b){a+="";if(!E(a))throw ba("iseccst",b);return a}function xa(a,b){if(a){if(a.constructor===a)throw ba("isecfn",b);if(a.window===a)throw ba("isecwindow",b);if(a.children&&(a.nodeName||a.prop&&a.attr&&a.find))throw ba("isecdom",b);if(a===Object)throw ba("isecobj",b);}return a}function kd(a,b){if(a){if(a.constructor===a)throw ba("isecfn",b);if(a===Wf||a===Xf||a===Yf)throw ba("isecff",b);}}function ld(a,b){if(a&&(a===(0).constructor||a=== +(!1).constructor||a==="".constructor||a==={}.constructor||a===[].constructor||a===Function.constructor))throw ba("isecaf",b);}function Zf(a,b){return"undefined"!==typeof a?a:b}function md(a,b){return"undefined"===typeof a?b:"undefined"===typeof b?a:a+b}function W(a,b){var d,c;switch(a.type){case s.Program:d=!0;n(a.body,function(a){W(a.expression,b);d=d&&a.expression.constant});a.constant=d;break;case s.Literal:a.constant=!0;a.toWatch=[];break;case s.UnaryExpression:W(a.argument,b);a.constant=a.argument.constant; +a.toWatch=a.argument.toWatch;break;case s.BinaryExpression:W(a.left,b);W(a.right,b);a.constant=a.left.constant&&a.right.constant;a.toWatch=a.left.toWatch.concat(a.right.toWatch);break;case s.LogicalExpression:W(a.left,b);W(a.right,b);a.constant=a.left.constant&&a.right.constant;a.toWatch=a.constant?[]:[a];break;case s.ConditionalExpression:W(a.test,b);W(a.alternate,b);W(a.consequent,b);a.constant=a.test.constant&&a.alternate.constant&&a.consequent.constant;a.toWatch=a.constant?[]:[a];break;case s.Identifier:a.constant= +!1;a.toWatch=[a];break;case s.MemberExpression:W(a.object,b);a.computed&&W(a.property,b);a.constant=a.object.constant&&(!a.computed||a.property.constant);a.toWatch=[a];break;case s.CallExpression:d=a.filter?!b(a.callee.name).$stateful:!1;c=[];n(a.arguments,function(a){W(a,b);d=d&&a.constant;a.constant||c.push.apply(c,a.toWatch)});a.constant=d;a.toWatch=a.filter&&!b(a.callee.name).$stateful?c:[a];break;case s.AssignmentExpression:W(a.left,b);W(a.right,b);a.constant=a.left.constant&&a.right.constant; +a.toWatch=[a];break;case s.ArrayExpression:d=!0;c=[];n(a.elements,function(a){W(a,b);d=d&&a.constant;a.constant||c.push.apply(c,a.toWatch)});a.constant=d;a.toWatch=c;break;case s.ObjectExpression:d=!0;c=[];n(a.properties,function(a){W(a.value,b);d=d&&a.value.constant;a.value.constant||c.push.apply(c,a.value.toWatch)});a.constant=d;a.toWatch=c;break;case s.ThisExpression:a.constant=!1,a.toWatch=[]}}function nd(a){if(1==a.length){a=a[0].expression;var b=a.toWatch;return 1!==b.length?b:b[0]!==a?b:u}} +function od(a){return a.type===s.Identifier||a.type===s.MemberExpression}function pd(a){if(1===a.body.length&&od(a.body[0].expression))return{type:s.AssignmentExpression,left:a.body[0].expression,right:{type:s.NGValueParameter},operator:"="}}function qd(a){return 0===a.body.length||1===a.body.length&&(a.body[0].expression.type===s.Literal||a.body[0].expression.type===s.ArrayExpression||a.body[0].expression.type===s.ObjectExpression)}function rd(a,b){this.astBuilder=a;this.$filter=b}function sd(a, +b){this.astBuilder=a;this.$filter=b}function Fb(a){return"constructor"==a}function ec(a){return z(a.valueOf)?a.valueOf():$f.call(a)}function kf(){var a=$(),b=$();this.$get=["$filter",function(d){function c(a,b){return null==a||null==b?a===b:"object"===typeof a&&(a=ec(a),"object"===typeof a)?!1:a===b||a!==a&&b!==b}function e(a,b,d,e,f){var g=e.inputs,h;if(1===g.length){var k=c,g=g[0];return a.$watch(function(a){var b=g(a);c(b,k)||(h=e(a,u,u,[b]),k=b&&ec(b));return h},b,d,f)}for(var l=[],m=[],r=0,n= +g.length;r=this.promise.$$state.status&&d&&d.length&&a(function(){for(var a,e,f=0,g=d.length;fa)for(b in l++,f)qa.call(e,b)||(n--,delete f[b])}else f!==e&&(f=e,l++);return l}}c.$stateful=!0;var d=this,e,f,g,k=1n&&(v=4-n,q[v]||(q[v]=[]),q[v].push({msg:z(a.exp)?"fn: "+(a.exp.name||a.exp.toString()):a.exp,newVal:f,oldVal:h}));else if(a===c){r=!1;break a}}catch(y){g(y)}if(!(l=A.$$watchersCount&&A.$$childHead||A!==this&&A.$$nextSibling))for(;A!==this&&!(l=A.$$nextSibling);)A=A.$parent}while(A=l);if((r||u.length)&&!n--)throw w.$$phase=null,d("infdig", +b,q);}while(r||u.length);for(w.$$phase=null;L.length;)try{L.shift()()}catch(x){g(x)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this===w&&k.$$applicationDestroyed();A(this,-this.$$watchersCount);for(var b in this.$$listenerCount)v(this,this.$$listenerCount[b],b);a&&a.$$childHead==this&&(a.$$childHead=this.$$nextSibling);a&&a.$$childTail==this&&(a.$$childTail=this.$$prevSibling);this.$$prevSibling&&(this.$$prevSibling.$$nextSibling= +this.$$nextSibling);this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling);this.$destroy=this.$digest=this.$apply=this.$evalAsync=this.$applyAsync=x;this.$on=this.$watch=this.$watchGroup=function(){return x};this.$$listeners={};this.$$nextSibling=null;m(this)}},$eval:function(a,b){return h(a)(this,b)},$evalAsync:function(a,b){w.$$phase||u.length||k.defer(function(){u.length&&w.$digest()});u.push({scope:this,expression:a,locals:b})},$$postDigest:function(a){L.push(a)},$apply:function(a){try{t("$apply"); +try{return this.$eval(a)}finally{w.$$phase=null}}catch(b){g(b)}finally{try{w.$digest()}catch(c){throw g(c),c;}}},$applyAsync:function(a){function b(){c.$eval(a)}var c=this;a&&aa.push(b);C()},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){var d=c.indexOf(b);-1!==d&&(c[d]=null,v(e,1,a))}},$emit:function(a,b){var c=[],d,e=this,f=!1,h= +{name:a,targetScope:e,stopPropagation:function(){f=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},k=cb([h],arguments,1),l,m;do{d=e.$$listeners[a]||c;h.currentScope=e;l=0;for(m=d.length;lHa)throw ya("iequirks");var c=ia(la);c.isEnabled=function(){return a};c.trustAs=d.trustAs;c.getTrusted=d.getTrusted;c.valueOf=d.valueOf;a||(c.trustAs=c.getTrusted=function(a,b){return b},c.valueOf=Ya);c.parseAs=function(a,d){var e=b(d);return e.literal&&e.constant?e:b(d,function(b){return c.getTrusted(a,b)})};var e=c.parseAs,f=c.getTrusted,g=c.trustAs;n(la,function(a, +b){var d=F(b);c[fb("parse_as_"+d)]=function(b){return e(a,b)};c[fb("get_trusted_"+d)]=function(b){return f(a,b)};c[fb("trust_as_"+d)]=function(b){return g(a,b)}});return c}]}function qf(){this.$get=["$window","$document",function(a,b){var d={},c=ea((/android (\d+)/.exec(F((a.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((a.navigator||{}).userAgent),f=b[0]||{},g,h=/^(Moz|webkit|ms)(?=[A-Z])/,k=f.body&&f.body.style,l=!1,m=!1;if(k){for(var r in k)if(l=h.exec(r)){g=l[0];g=g.substr(0,1).toUpperCase()+ +g.substr(1);break}g||(g="WebkitOpacity"in k&&"webkit");l=!!("transition"in k||g+"Transition"in k);m=!!("animation"in k||g+"Animation"in k);!c||l&&m||(l=E(k.webkitTransition),m=E(k.webkitAnimation))}return{history:!(!a.history||!a.history.pushState||4>c||e),hasEvent:function(a){if("input"===a&&11>=Ha)return!1;if(q(d[a])){var b=f.createElement("div");d[a]="on"+a in b}return d[a]},csp:Ba(),vendorPrefix:g,transitions:l,animations:m,android:c}}]}function sf(){this.$get=["$templateCache","$http","$q","$sce", +function(a,b,d,c){function e(f,g){e.totalPendingRequests++;E(f)&&a.get(f)||(f=c.getTrustedResourceUrl(f));var h=b.defaults&&b.defaults.transformResponse;I(h)?h=h.filter(function(a){return a!==$b}):h===$b&&(h=null);return b.get(f,{cache:a,transformResponse:h})["finally"](function(){e.totalPendingRequests--}).then(function(b){a.put(f,b.data);return b.data},function(a){if(!g)throw ha("tpload",f,a.status,a.statusText);return d.reject(a)})}e.totalPendingRequests=0;return e}]}function tf(){this.$get=["$rootScope", +"$browser","$location",function(a,b,d){return{findBindings:function(a,b,d){a=a.getElementsByClassName("ng-binding");var g=[];n(a,function(a){var c=fa.element(a).data("$binding");c&&n(c,function(c){d?(new RegExp("(^|\\s)"+ud(b)+"(\\s|\\||$)")).test(c)&&g.push(a):-1!=c.indexOf(b)&&g.push(a)})});return g},findModels:function(a,b,d){for(var g=["ng-","data-ng-","ng\\:"],h=0;ha;a=Math.abs(a);var g=Infinity===a;if(!g&&!isFinite(a))return"";var h=a+"",k="",l=!1,m=[];g&&(k="\u221e");if(!g&&-1!==h.indexOf("e")){var r=h.match(/([\d\.]+)e(-?)(\d+)/);r&&"-"==r[2]&&r[3]>e+1?a=0:(k=h,l=!0)}if(g||l)0a&&(k=a.toFixed(e),a=parseFloat(k),k=k.replace(ic,c));else{g=(h.split(ic)[1]||"").length; +q(e)&&(e=Math.min(Math.max(b.minFrac,g),b.maxFrac));a=+(Math.round(+(a.toString()+"e"+e)).toString()+"e"+-e);var g=(""+a).split(ic),h=g[0],g=g[1]||"",r=0,t=b.lgSize,n=b.gSize;if(h.length>=t+n)for(r=h.length-t,l=0;la&&(c="-",a=-a);for(a=""+a;a.length-d)e+=d;0===e&&-12==d&&(e=12);return Gb(e,b,c)}}function Hb(a,b){return function(d,c){var e=d["get"+a](),f=sb(b?"SHORT"+a:a);return c[f][e]}}function Dd(a){var b=(new Date(a,0,1)).getDay();return new Date(a,0,(4>=b?5:12)-b)}function Ed(a){return function(b){var d=Dd(b.getFullYear());b=+new Date(b.getFullYear(),b.getMonth(),b.getDate()+(4-b.getDay()))- ++d;b=1+Math.round(b/6048E5);return Gb(b,a)}}function jc(a,b){return 0>=a.getFullYear()?b.ERAS[0]:b.ERAS[1]}function zd(a){function b(a){var b;if(b=a.match(d)){a=new Date(0);var f=0,g=0,h=b[8]?a.setUTCFullYear:a.setFullYear,k=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=ea(b[9]+b[10]),g=ea(b[9]+b[11]));h.call(a,ea(b[1]),ea(b[2])-1,ea(b[3]));f=ea(b[4]||0)-f;g=ea(b[5]||0)-g;h=ea(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));k.call(a,f,g,h,b)}return a}var d=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; +return function(c,d,f){var g="",h=[],k,l;d=d||"mediumDate";d=a.DATETIME_FORMATS[d]||d;E(c)&&(c=hg.test(c)?ea(c):b(c));Q(c)&&(c=new Date(c));if(!da(c)||!isFinite(c.getTime()))return c;for(;d;)(l=ig.exec(d))?(h=cb(h,l,1),d=h.pop()):(h.push(d),d=null);var m=c.getTimezoneOffset();f&&(m=vc(f,c.getTimezoneOffset()),c=Pb(c,f,!0));n(h,function(b){k=jg[b];g+=k?k(c,a.DATETIME_FORMATS,m):b.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function cg(){return function(a,b){q(b)&&(b=2);return db(a,b)}}function dg(){return function(a, +b,d){b=Infinity===Math.abs(Number(b))?Number(b):ea(b);if(isNaN(b))return a;Q(a)&&(a=a.toString());if(!I(a)&&!E(a))return a;d=!d||isNaN(d)?0:ea(d);d=0>d?Math.max(0,a.length+d):d;return 0<=b?a.slice(d,d+b):0===d?a.slice(b,a.length):a.slice(Math.max(0,d+b),d)}}function Bd(a){function b(b,d){d=d?-1:1;return b.map(function(b){var c=1,h=Ya;if(z(b))h=b;else if(E(b)){if("+"==b.charAt(0)||"-"==b.charAt(0))c="-"==b.charAt(0)?-1:1,b=b.substring(1);if(""!==b&&(h=a(b),h.constant))var k=h(),h=function(a){return a[k]}}return{get:h, +descending:c*d}})}function d(a){switch(typeof a){case "number":case "boolean":case "string":return!0;default:return!1}}return function(a,e,f){if(!za(a))return a;I(e)||(e=[e]);0===e.length&&(e=["+"]);var g=b(e,f);g.push({get:function(){return{}},descending:f?-1:1});a=Array.prototype.map.call(a,function(a,b){return{value:a,predicateValues:g.map(function(c){var e=c.get(a);c=typeof e;if(null===e)c="string",e="null";else if("string"===c)e=e.toLowerCase();else if("object"===c)a:{if("function"===typeof e.valueOf&& +(e=e.valueOf(),d(e)))break a;if(qc(e)&&(e=e.toString(),d(e)))break a;e=b}return{value:e,type:c}})}});a.sort(function(a,b){for(var c=0,d=0,e=g.length;db||37<=b&&40>=b||m(a,this,this.value)});if(e.hasEvent("paste"))b.on("paste cut", +m)}b.on("change",k);c.$render=function(){var a=c.$isEmpty(c.$viewValue)?"":c.$viewValue;b.val()!==a&&b.val(a)}}function Kb(a,b){return function(d,c){var e,f;if(da(d))return d;if(E(d)){'"'==d.charAt(0)&&'"'==d.charAt(d.length-1)&&(d=d.substring(1,d.length-1));if(kg.test(d))return new Date(d);a.lastIndex=0;if(e=a.exec(d))return e.shift(),f=c?{yyyy:c.getFullYear(),MM:c.getMonth()+1,dd:c.getDate(),HH:c.getHours(),mm:c.getMinutes(),ss:c.getSeconds(),sss:c.getMilliseconds()/1E3}:{yyyy:1970,MM:1,dd:1,HH:0, +mm:0,ss:0,sss:0},n(e,function(a,c){c=s};g.$observe("min",function(a){s=n(a);h.$validate()})}if(y(g.max)||g.ngMax){var p;h.$validators.max=function(a){return!r(a)||q(p)||d(a)<=p};g.$observe("max",function(a){p=n(a);h.$validate()})}}}function Hd(a,b,d,c){(c.$$hasNativeValidators=H(b[0].validity))&&c.$parsers.push(function(a){var c=b.prop("validity")||{}; +return c.badInput&&!c.typeMismatch?u:a})}function Id(a,b,d,c,e){if(y(c)){a=a(c);if(!a.constant)throw lb("constexpr",d,c);return a(b)}return e}function lc(a,b){a="ngClass"+a;return["$animate",function(d){function c(a,b){var c=[],d=0;a:for(;d(?:<\/\1>|)$/,Tb=/<|&#?\w+;/, +Cf=/<([\w:-]+)/,Df=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,ka={option:[1,'"],thead:[1,"
    {$my_team->get_name()}{$my_team->get_name()|replace:"_":" "}Exercice {$i}
    ","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ka.optgroup=ka.option;ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead;ka.th=ka.td;var Kf=Node.prototype.contains||function(a){return!!(this.compareDocumentPosition(a)& +16)},Pa=N.prototype={ready:function(a){function b(){d||(d=!0,a())}var d=!1;"complete"===X.readyState?setTimeout(b):(this.on("DOMContentLoaded",b),N(S).on("load",b))},toString:function(){var a=[];n(this,function(b){a.push(""+b)});return"["+a.join(", ")+"]"},eq:function(a){return 0<=a?B(this[a]):B(this[this.length+a])},length:0,push:mg,sort:[].sort,splice:[].splice},Cb={};n("multiple selected checked disabled readOnly required open".split(" "),function(a){Cb[F(a)]=a});var Rc={};n("input select option textarea button form details".split(" "), +function(a){Rc[a]=!0});var Zc={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"};n({data:Wb,removeData:vb,hasData:function(a){for(var b in gb[a.ng339])return!0;return!1}},function(a,b){N[b]=a});n({data:Wb,inheritedData:Bb,scope:function(a){return B.data(a,"$scope")||Bb(a.parentNode||a,["$isolateScope","$scope"])},isolateScope:function(a){return B.data(a,"$isolateScope")||B.data(a,"$isolateScopeNoTemplate")},controller:Oc,injector:function(a){return Bb(a, +"$injector")},removeAttr:function(a,b){a.removeAttribute(b)},hasClass:yb,css:function(a,b,d){b=fb(b);if(y(d))a.style[b]=d;else return a.style[b]},attr:function(a,b,d){var c=a.nodeType;if(c!==Na&&2!==c&&8!==c)if(c=F(b),Cb[c])if(y(d))d?(a[b]=!0,a.setAttribute(b,c)):(a[b]=!1,a.removeAttribute(c));else return a[b]||(a.attributes.getNamedItem(b)||x).specified?c:u;else if(y(d))a.setAttribute(b,d);else if(a.getAttribute)return a=a.getAttribute(b,2),null===a?u:a},prop:function(a,b,d){if(y(d))a[b]=d;else return a[b]}, +text:function(){function a(a,d){if(q(d)){var c=a.nodeType;return 1===c||c===Na?a.textContent:""}a.textContent=d}a.$dv="";return a}(),val:function(a,b){if(q(b)){if(a.multiple&&"select"===ta(a)){var d=[];n(a.options,function(a){a.selected&&d.push(a.value||a.text)});return 0===d.length?null:d}return a.value}a.value=b},html:function(a,b){if(q(b))return a.innerHTML;ub(a,!0);a.innerHTML=b},empty:Pc},function(a,b){N.prototype[b]=function(b,c){var e,f,g=this.length;if(a!==Pc&&q(2==a.length&&a!==yb&&a!==Oc? +b:c)){if(H(b)){for(e=0;e <= >= && || ! = |".split(" "),function(a){Lb[a]=!0});var sg={n:"\n",f:"\f",r:"\r", +t:"\t",v:"\v","'":"'",'"':'"'},fc=function(a){this.options=a};fc.prototype={constructor:fc,lex:function(a){this.text=a;this.index=0;for(this.tokens=[];this.index=a&&"string"===typeof a},isWhitespace:function(a){return" "===a||"\r"===a|| +"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,b,d){d=d||this.index;b=y(b)?"s "+b+"-"+this.index+" ["+this.text.substring(b,d)+"]":" "+d;throw ba("lexerr",a,b,this.text);},readNumber:function(){for(var a="",b=this.index;this.index","<=",">=");)a={type:s.BinaryExpression,operator:b.text,left:a,right:this.additive()};return a},additive:function(){for(var a=this.multiplicative(),b;b=this.expect("+","-");)a={type:s.BinaryExpression,operator:b.text,left:a,right:this.multiplicative()};return a},multiplicative:function(){for(var a=this.unary(),b;b=this.expect("*","/","%");)a={type:s.BinaryExpression,operator:b.text, +left:a,right:this.unary()};return a},unary:function(){var a;return(a=this.expect("+","-","!"))?{type:s.UnaryExpression,operator:a.text,prefix:!0,argument:this.unary()}:this.primary()},primary:function(){var a;this.expect("(")?(a=this.filterChain(),this.consume(")")):this.expect("[")?a=this.arrayDeclaration():this.expect("{")?a=this.object():this.constants.hasOwnProperty(this.peek().text)?a=bb(this.constants[this.consume().text]):this.peek().identifier?a=this.identifier():this.peek().constant?a=this.constant(): +this.throwError("not a primary expression",this.peek());for(var b;b=this.expect("(","[",".");)"("===b.text?(a={type:s.CallExpression,callee:a,arguments:this.parseArguments()},this.consume(")")):"["===b.text?(a={type:s.MemberExpression,object:a,property:this.expression(),computed:!0},this.consume("]")):"."===b.text?a={type:s.MemberExpression,object:a,property:this.identifier(),computed:!1}:this.throwError("IMPOSSIBLE");return a},filter:function(a){a=[a];for(var b={type:s.CallExpression,callee:this.identifier(), +arguments:a,filter:!0};this.expect(":");)a.push(this.expression());return b},parseArguments:function(){var a=[];if(")"!==this.peekToken().text){do a.push(this.expression());while(this.expect(","))}return a},identifier:function(){var a=this.consume();a.identifier||this.throwError("is not a valid identifier",a);return{type:s.Identifier,name:a.text}},constant:function(){return{type:s.Literal,value:this.consume().value}},arrayDeclaration:function(){var a=[];if("]"!==this.peekToken().text){do{if(this.peek("]"))break; +a.push(this.expression())}while(this.expect(","))}this.consume("]");return{type:s.ArrayExpression,elements:a}},object:function(){var a=[],b;if("}"!==this.peekToken().text){do{if(this.peek("}"))break;b={type:s.Property,kind:"init"};this.peek().constant?b.key=this.constant():this.peek().identifier?b.key=this.identifier():this.throwError("invalid key",this.peek());this.consume(":");b.value=this.expression();a.push(b)}while(this.expect(","))}this.consume("}");return{type:s.ObjectExpression,properties:a}}, +throwError:function(a,b){throw ba("syntax",b.text,a,b.index+1,this.text,this.text.substring(b.index));},consume:function(a){if(0===this.tokens.length)throw ba("ueoe",this.text);var b=this.expect(a);b||this.throwError("is unexpected, expecting ["+a+"]",this.peek());return b},peekToken:function(){if(0===this.tokens.length)throw ba("ueoe",this.text);return this.tokens[0]},peek:function(a,b,d,c){return this.peekAhead(0,a,b,d,c)},peekAhead:function(a,b,d,c,e){if(this.tokens.length>a){a=this.tokens[a]; +var f=a.text;if(f===b||f===d||f===c||f===e||!(b||d||c||e))return a}return!1},expect:function(a,b,d,c){return(a=this.peek(a,b,d,c))?(this.tokens.shift(),a):!1},constants:{"true":{type:s.Literal,value:!0},"false":{type:s.Literal,value:!1},"null":{type:s.Literal,value:null},undefined:{type:s.Literal,value:u},"this":{type:s.ThisExpression}}};rd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.state={nextId:0,filters:{},expensiveChecks:b,fn:{vars:[],body:[],own:{}},assign:{vars:[], +body:[],own:{}},inputs:[]};W(c,d.$filter);var e="",f;this.stage="assign";if(f=pd(c))this.state.computing="assign",e=this.nextId(),this.recurse(f,e),this.return_(e),e="fn.assign="+this.generateFunction("assign","s,v,l");f=nd(c.body);d.stage="inputs";n(f,function(a,b){var c="fn"+b;d.state[c]={vars:[],body:[],own:{}};d.state.computing=c;var e=d.nextId();d.recurse(a,e);d.return_(e);d.state.inputs.push(c);a.watchId=b});this.state.computing="fn";this.stage="main";this.recurse(c);e='"'+this.USE+" "+this.STRICT+ +'";\n'+this.filterPrefix()+"var fn="+this.generateFunction("fn","s,l,a,i")+e+this.watchFns()+"return fn;";e=(new Function("$filter","ensureSafeMemberName","ensureSafeObject","ensureSafeFunction","getStringValue","ensureSafeAssignContext","ifDefined","plus","text",e))(this.$filter,Va,xa,kd,jd,ld,Zf,md,a);this.state=this.stage=u;e.literal=qd(c);e.constant=c.constant;return e},USE:"use",STRICT:"strict",watchFns:function(){var a=[],b=this.state.inputs,d=this;n(b,function(b){a.push("var "+b+"="+d.generateFunction(b, +"s"))});b.length&&a.push("fn.inputs=["+b.join(",")+"];");return a.join("")},generateFunction:function(a,b){return"function("+b+"){"+this.varsPrefix(a)+this.body(a)+"};"},filterPrefix:function(){var a=[],b=this;n(this.state.filters,function(d,c){a.push(d+"=$filter("+b.escape(c)+")")});return a.length?"var "+a.join(",")+";":""},varsPrefix:function(a){return this.state[a].vars.length?"var "+this.state[a].vars.join(",")+";":""},body:function(a){return this.state[a].body.join("")},recurse:function(a,b, +d,c,e,f){var g,h,k=this,l,m;c=c||x;if(!f&&y(a.watchId))b=b||this.nextId(),this.if_("i",this.lazyAssign(b,this.computedMember("i",a.watchId)),this.lazyRecurse(a,b,d,c,e,!0));else switch(a.type){case s.Program:n(a.body,function(b,c){k.recurse(b.expression,u,u,function(a){h=a});c!==a.body.length-1?k.current().body.push(h,";"):k.return_(h)});break;case s.Literal:m=this.escape(a.value);this.assign(b,m);c(m);break;case s.UnaryExpression:this.recurse(a.argument,u,u,function(a){h=a});m=a.operator+"("+this.ifDefined(h, +0)+")";this.assign(b,m);c(m);break;case s.BinaryExpression:this.recurse(a.left,u,u,function(a){g=a});this.recurse(a.right,u,u,function(a){h=a});m="+"===a.operator?this.plus(g,h):"-"===a.operator?this.ifDefined(g,0)+a.operator+this.ifDefined(h,0):"("+g+")"+a.operator+"("+h+")";this.assign(b,m);c(m);break;case s.LogicalExpression:b=b||this.nextId();k.recurse(a.left,b);k.if_("&&"===a.operator?b:k.not(b),k.lazyRecurse(a.right,b));c(b);break;case s.ConditionalExpression:b=b||this.nextId();k.recurse(a.test, +b);k.if_(b,k.lazyRecurse(a.alternate,b),k.lazyRecurse(a.consequent,b));c(b);break;case s.Identifier:b=b||this.nextId();d&&(d.context="inputs"===k.stage?"s":this.assign(this.nextId(),this.getHasOwnProperty("l",a.name)+"?l:s"),d.computed=!1,d.name=a.name);Va(a.name);k.if_("inputs"===k.stage||k.not(k.getHasOwnProperty("l",a.name)),function(){k.if_("inputs"===k.stage||"s",function(){e&&1!==e&&k.if_(k.not(k.nonComputedMember("s",a.name)),k.lazyAssign(k.nonComputedMember("s",a.name),"{}"));k.assign(b,k.nonComputedMember("s", +a.name))})},b&&k.lazyAssign(b,k.nonComputedMember("l",a.name)));(k.state.expensiveChecks||Fb(a.name))&&k.addEnsureSafeObject(b);c(b);break;case s.MemberExpression:g=d&&(d.context=this.nextId())||this.nextId();b=b||this.nextId();k.recurse(a.object,g,u,function(){k.if_(k.notNull(g),function(){if(a.computed)h=k.nextId(),k.recurse(a.property,h),k.getStringValue(h),k.addEnsureSafeMemberName(h),e&&1!==e&&k.if_(k.not(k.computedMember(g,h)),k.lazyAssign(k.computedMember(g,h),"{}")),m=k.ensureSafeObject(k.computedMember(g, +h)),k.assign(b,m),d&&(d.computed=!0,d.name=h);else{Va(a.property.name);e&&1!==e&&k.if_(k.not(k.nonComputedMember(g,a.property.name)),k.lazyAssign(k.nonComputedMember(g,a.property.name),"{}"));m=k.nonComputedMember(g,a.property.name);if(k.state.expensiveChecks||Fb(a.property.name))m=k.ensureSafeObject(m);k.assign(b,m);d&&(d.computed=!1,d.name=a.property.name)}},function(){k.assign(b,"undefined")});c(b)},!!e);break;case s.CallExpression:b=b||this.nextId();a.filter?(h=k.filter(a.callee.name),l=[],n(a.arguments, +function(a){var b=k.nextId();k.recurse(a,b);l.push(b)}),m=h+"("+l.join(",")+")",k.assign(b,m),c(b)):(h=k.nextId(),g={},l=[],k.recurse(a.callee,h,g,function(){k.if_(k.notNull(h),function(){k.addEnsureSafeFunction(h);n(a.arguments,function(a){k.recurse(a,k.nextId(),u,function(a){l.push(k.ensureSafeObject(a))})});g.name?(k.state.expensiveChecks||k.addEnsureSafeObject(g.context),m=k.member(g.context,g.name,g.computed)+"("+l.join(",")+")"):m=h+"("+l.join(",")+")";m=k.ensureSafeObject(m);k.assign(b,m)}, +function(){k.assign(b,"undefined")});c(b)}));break;case s.AssignmentExpression:h=this.nextId();g={};if(!od(a.left))throw ba("lval");this.recurse(a.left,u,g,function(){k.if_(k.notNull(g.context),function(){k.recurse(a.right,h);k.addEnsureSafeObject(k.member(g.context,g.name,g.computed));k.addEnsureSafeAssignContext(g.context);m=k.member(g.context,g.name,g.computed)+a.operator+h;k.assign(b,m);c(b||m)})},1);break;case s.ArrayExpression:l=[];n(a.elements,function(a){k.recurse(a,k.nextId(),u,function(a){l.push(a)})}); +m="["+l.join(",")+"]";this.assign(b,m);c(m);break;case s.ObjectExpression:l=[];n(a.properties,function(a){k.recurse(a.value,k.nextId(),u,function(b){l.push(k.escape(a.key.type===s.Identifier?a.key.name:""+a.key.value)+":"+b)})});m="{"+l.join(",")+"}";this.assign(b,m);c(m);break;case s.ThisExpression:this.assign(b,"s");c("s");break;case s.NGValueParameter:this.assign(b,"v"),c("v")}},getHasOwnProperty:function(a,b){var d=a+"."+b,c=this.current().own;c.hasOwnProperty(d)||(c[d]=this.nextId(!1,a+"&&("+ +this.escape(b)+" in "+a+")"));return c[d]},assign:function(a,b){if(a)return this.current().body.push(a,"=",b,";"),a},filter:function(a){this.state.filters.hasOwnProperty(a)||(this.state.filters[a]=this.nextId(!0));return this.state.filters[a]},ifDefined:function(a,b){return"ifDefined("+a+","+this.escape(b)+")"},plus:function(a,b){return"plus("+a+","+b+")"},return_:function(a){this.current().body.push("return ",a,";")},if_:function(a,b,d){if(!0===a)b();else{var c=this.current().body;c.push("if(",a, +"){");b();c.push("}");d&&(c.push("else{"),d(),c.push("}"))}},not:function(a){return"!("+a+")"},notNull:function(a){return a+"!=null"},nonComputedMember:function(a,b){return a+"."+b},computedMember:function(a,b){return a+"["+b+"]"},member:function(a,b,d){return d?this.computedMember(a,b):this.nonComputedMember(a,b)},addEnsureSafeObject:function(a){this.current().body.push(this.ensureSafeObject(a),";")},addEnsureSafeMemberName:function(a){this.current().body.push(this.ensureSafeMemberName(a),";")}, +addEnsureSafeFunction:function(a){this.current().body.push(this.ensureSafeFunction(a),";")},addEnsureSafeAssignContext:function(a){this.current().body.push(this.ensureSafeAssignContext(a),";")},ensureSafeObject:function(a){return"ensureSafeObject("+a+",text)"},ensureSafeMemberName:function(a){return"ensureSafeMemberName("+a+",text)"},ensureSafeFunction:function(a){return"ensureSafeFunction("+a+",text)"},getStringValue:function(a){this.assign(a,"getStringValue("+a+",text)")},ensureSafeAssignContext:function(a){return"ensureSafeAssignContext("+ +a+",text)"},lazyRecurse:function(a,b,d,c,e,f){var g=this;return function(){g.recurse(a,b,d,c,e,f)}},lazyAssign:function(a,b){var d=this;return function(){d.assign(a,b)}},stringEscapeRegex:/[^ a-zA-Z0-9]/g,stringEscapeFn:function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)},escape:function(a){if(E(a))return"'"+a.replace(this.stringEscapeRegex,this.stringEscapeFn)+"'";if(Q(a))return a.toString();if(!0===a)return"true";if(!1===a)return"false";if(null===a)return"null";if("undefined"=== +typeof a)return"undefined";throw ba("esc");},nextId:function(a,b){var d="v"+this.state.nextId++;a||this.current().vars.push(d+(b?"="+b:""));return d},current:function(){return this.state[this.state.computing]}};sd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.expression=a;this.expensiveChecks=b;W(c,d.$filter);var e,f;if(e=pd(c))f=this.recurse(e);e=nd(c.body);var g;e&&(g=[],n(e,function(a,b){var c=d.recurse(a);a.input=c;g.push(c);a.watchId=b}));var h=[];n(c.body,function(a){h.push(d.recurse(a.expression))}); +e=0===c.body.length?function(){}:1===c.body.length?h[0]:function(a,b){var c;n(h,function(d){c=d(a,b)});return c};f&&(e.assign=function(a,b,c){return f(a,c,b)});g&&(e.inputs=g);e.literal=qd(c);e.constant=c.constant;return e},recurse:function(a,b,d){var c,e,f=this,g;if(a.input)return this.inputs(a.input,a.watchId);switch(a.type){case s.Literal:return this.value(a.value,b);case s.UnaryExpression:return e=this.recurse(a.argument),this["unary"+a.operator](e,b);case s.BinaryExpression:return c=this.recurse(a.left), +e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case s.LogicalExpression:return c=this.recurse(a.left),e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case s.ConditionalExpression:return this["ternary?:"](this.recurse(a.test),this.recurse(a.alternate),this.recurse(a.consequent),b);case s.Identifier:return Va(a.name,f.expression),f.identifier(a.name,f.expensiveChecks||Fb(a.name),b,d,f.expression);case s.MemberExpression:return c=this.recurse(a.object,!1,!!d),a.computed||(Va(a.property.name, +f.expression),e=a.property.name),a.computed&&(e=this.recurse(a.property)),a.computed?this.computedMember(c,e,b,d,f.expression):this.nonComputedMember(c,e,f.expensiveChecks,b,d,f.expression);case s.CallExpression:return g=[],n(a.arguments,function(a){g.push(f.recurse(a))}),a.filter&&(e=this.$filter(a.callee.name)),a.filter||(e=this.recurse(a.callee,!0)),a.filter?function(a,c,d,f){for(var r=[],n=0;n":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)>b(c,e,f,g);return d?{value:c}:c}},"binary<=":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)<=b(c,e,f,g);return d?{value:c}:c}},"binary>=":function(a,b,d){return function(c, +e,f,g){c=a(c,e,f,g)>=b(c,e,f,g);return d?{value:c}:c}},"binary&&":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)&&b(c,e,f,g);return d?{value:c}:c}},"binary||":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)||b(c,e,f,g);return d?{value:c}:c}},"ternary?:":function(a,b,d,c){return function(e,f,g,h){e=a(e,f,g,h)?b(e,f,g,h):d(e,f,g,h);return c?{value:e}:e}},value:function(a,b){return function(){return b?{context:u,name:u,value:a}:a}},identifier:function(a,b,d,c,e){return function(f,g,h,k){f= +g&&a in g?g:f;c&&1!==c&&f&&!f[a]&&(f[a]={});g=f?f[a]:u;b&&xa(g,e);return d?{context:f,name:a,value:g}:g}},computedMember:function(a,b,d,c,e){return function(f,g,h,k){var l=a(f,g,h,k),m,n;null!=l&&(m=b(f,g,h,k),m=jd(m),Va(m,e),c&&1!==c&&l&&!l[m]&&(l[m]={}),n=l[m],xa(n,e));return d?{context:l,name:m,value:n}:n}},nonComputedMember:function(a,b,d,c,e,f){return function(g,h,k,l){g=a(g,h,k,l);e&&1!==e&&g&&!g[b]&&(g[b]={});h=null!=g?g[b]:u;(d||Fb(b))&&xa(h,f);return c?{context:g,name:b,value:h}:h}},inputs:function(a, +b){return function(d,c,e,f){return f?f[b]:a(d,c,e)}}};var gc=function(a,b,d){this.lexer=a;this.$filter=b;this.options=d;this.ast=new s(this.lexer);this.astCompiler=d.csp?new sd(this.ast,b):new rd(this.ast,b)};gc.prototype={constructor:gc,parse:function(a){return this.astCompiler.compile(a,this.options.expensiveChecks)}};$();$();var $f=Object.prototype.valueOf,ya=G("$sce"),la={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},ha=G("$compile"),Y=X.createElement("a"),wd=wa(S.location.href); +xd.$inject=["$document"];Jc.$inject=["$provide"];yd.$inject=["$locale"];Ad.$inject=["$locale"];var ic=".",jg={yyyy:ca("FullYear",4),yy:ca("FullYear",2,0,!0),y:ca("FullYear",1),MMMM:Hb("Month"),MMM:Hb("Month",!0),MM:ca("Month",2,1),M:ca("Month",1,1),dd:ca("Date",2),d:ca("Date",1),HH:ca("Hours",2),H:ca("Hours",1),hh:ca("Hours",2,-12),h:ca("Hours",1,-12),mm:ca("Minutes",2),m:ca("Minutes",1),ss:ca("Seconds",2),s:ca("Seconds",1),sss:ca("Milliseconds",3),EEEE:Hb("Day"),EEE:Hb("Day",!0),a:function(a,b){return 12> +a.getHours()?b.AMPMS[0]:b.AMPMS[1]},Z:function(a,b,d){a=-1*d;return a=(0<=a?"+":"")+(Gb(Math[0=a.getFullYear()?b.ERANAMES[0]:b.ERANAMES[1]}},ig=/((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,hg=/^\-?\d+$/;zd.$inject=["$locale"];var eg=na(F),fg=na(sb);Bd.$inject=["$parse"];var he=na({restrict:"E",compile:function(a,b){if(!b.href&&!b.xlinkHref)return function(a, +b){if("a"===b[0].nodeName.toLowerCase()){var e="[object SVGAnimatedString]"===sa.call(b.prop("href"))?"xlink:href":"href";b.on("click",function(a){b.attr(e)||a.preventDefault()})}}}}),tb={};n(Cb,function(a,b){function d(a,d,e){a.$watch(e[c],function(a){e.$set(b,!!a)})}if("multiple"!=a){var c=va("ng-"+b),e=d;"checked"===a&&(e=function(a,b,e){e.ngModel!==e[c]&&d(a,b,e)});tb[c]=function(){return{restrict:"A",priority:100,link:e}}}});n(Zc,function(a,b){tb[b]=function(){return{priority:100,link:function(a, +c,e){if("ngPattern"===b&&"/"==e.ngPattern.charAt(0)&&(c=e.ngPattern.match(lg))){e.$set("ngPattern",new RegExp(c[1],c[2]));return}a.$watch(e[b],function(a){e.$set(b,a)})}}}});n(["src","srcset","href"],function(a){var b=va("ng-"+a);tb[b]=function(){return{priority:99,link:function(d,c,e){var f=a,g=a;"href"===a&&"[object SVGAnimatedString]"===sa.call(c.prop("href"))&&(g="xlinkHref",e.$attr[g]="xlink:href",f=null);e.$observe(b,function(b){b?(e.$set(g,b),Ha&&f&&c.prop(f,e[g])):"href"===a&&e.$set(g,null)})}}}}); +var Ib={$addControl:x,$$renameControl:function(a,b){a.$name=b},$removeControl:x,$setValidity:x,$setDirty:x,$setPristine:x,$setSubmitted:x};Fd.$inject=["$element","$attrs","$scope","$animate","$interpolate"];var Nd=function(a){return["$timeout","$parse",function(b,d){function c(a){return""===a?d('this[""]').assign:d(a).assign||x}return{name:"form",restrict:a?"EAC":"E",require:["form","^^?form"],controller:Fd,compile:function(d,f){d.addClass(Wa).addClass(mb);var g=f.name?"name":a&&f.ngForm?"ngForm": +!1;return{pre:function(a,d,e,f){var n=f[0];if(!("action"in e)){var q=function(b){a.$apply(function(){n.$commitViewValue();n.$setSubmitted()});b.preventDefault()};d[0].addEventListener("submit",q,!1);d.on("$destroy",function(){b(function(){d[0].removeEventListener("submit",q,!1)},0,!1)})}(f[1]||n.$$parentForm).$addControl(n);var s=g?c(n.$name):x;g&&(s(a,n),e.$observe(g,function(b){n.$name!==b&&(s(a,u),n.$$parentForm.$$renameControl(n,b),s=c(n.$name),s(a,n))}));d.on("$destroy",function(){n.$$parentForm.$removeControl(n); +s(a,u);M(n,Ib)})}}}}}]},ie=Nd(),ve=Nd(!0),kg=/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/,tg=/^[A-Za-z][A-Za-z\d.+-]*:\/*(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?(?:\/[\w#!:.?+=&%@\-/]*)?$/,ug=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,vg=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/,Od=/^(\d{4})-(\d{2})-(\d{2})$/,Pd=/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,mc=/^(\d{4})-W(\d\d)$/,Qd=/^(\d{4})-(\d\d)$/, +Rd=/^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,Sd={text:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c)},date:kb("date",Od,Kb(Od,["yyyy","MM","dd"]),"yyyy-MM-dd"),"datetime-local":kb("datetimelocal",Pd,Kb(Pd,"yyyy MM dd HH mm ss sss".split(" ")),"yyyy-MM-ddTHH:mm:ss.sss"),time:kb("time",Rd,Kb(Rd,["HH","mm","ss","sss"]),"HH:mm:ss.sss"),week:kb("week",mc,function(a,b){if(da(a))return a;if(E(a)){mc.lastIndex=0;var d=mc.exec(a);if(d){var c=+d[1],e=+d[2],f=d=0,g=0,h=0,k=Dd(c),e=7*(e-1);b&&(d=b.getHours(),f= +b.getMinutes(),g=b.getSeconds(),h=b.getMilliseconds());return new Date(c,0,k.getDate()+e,d,f,g,h)}}return NaN},"yyyy-Www"),month:kb("month",Qd,Kb(Qd,["yyyy","MM"]),"yyyy-MM"),number:function(a,b,d,c,e,f){Hd(a,b,d,c);jb(a,b,d,c,e,f);c.$$parserName="number";c.$parsers.push(function(a){return c.$isEmpty(a)?null:vg.test(a)?parseFloat(a):u});c.$formatters.push(function(a){if(!c.$isEmpty(a)){if(!Q(a))throw lb("numfmt",a);a=a.toString()}return a});if(y(d.min)||d.ngMin){var g;c.$validators.min=function(a){return c.$isEmpty(a)|| +q(g)||a>=g};d.$observe("min",function(a){y(a)&&!Q(a)&&(a=parseFloat(a,10));g=Q(a)&&!isNaN(a)?a:u;c.$validate()})}if(y(d.max)||d.ngMax){var h;c.$validators.max=function(a){return c.$isEmpty(a)||q(h)||a<=h};d.$observe("max",function(a){y(a)&&!Q(a)&&(a=parseFloat(a,10));h=Q(a)&&!isNaN(a)?a:u;c.$validate()})}},url:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c);c.$$parserName="url";c.$validators.url=function(a,b){var d=a||b;return c.$isEmpty(d)||tg.test(d)}},email:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c); +c.$$parserName="email";c.$validators.email=function(a,b){var d=a||b;return c.$isEmpty(d)||ug.test(d)}},radio:function(a,b,d,c){q(d.name)&&b.attr("name",++nb);b.on("click",function(a){b[0].checked&&c.$setViewValue(d.value,a&&a.type)});c.$render=function(){b[0].checked=d.value==c.$viewValue};d.$observe("value",c.$render)},checkbox:function(a,b,d,c,e,f,g,h){var k=Id(h,a,"ngTrueValue",d.ngTrueValue,!0),l=Id(h,a,"ngFalseValue",d.ngFalseValue,!1);b.on("click",function(a){c.$setViewValue(b[0].checked,a&& +a.type)});c.$render=function(){b[0].checked=c.$viewValue};c.$isEmpty=function(a){return!1===a};c.$formatters.push(function(a){return ma(a,k)});c.$parsers.push(function(a){return a?k:l})},hidden:x,button:x,submit:x,reset:x,file:x},Dc=["$browser","$sniffer","$filter","$parse",function(a,b,d,c){return{restrict:"E",require:["?ngModel"],link:{pre:function(e,f,g,h){h[0]&&(Sd[F(g.type)]||Sd.text)(e,f,g,h[0],b,a,d,c)}}}}],wg=/^(true|false|\d+)$/,Ne=function(){return{restrict:"A",priority:100,compile:function(a, +b){return wg.test(b.ngValue)?function(a,b,e){e.$set("value",a.$eval(e.ngValue))}:function(a,b,e){a.$watch(e.ngValue,function(a){e.$set("value",a)})}}}},ne=["$compile",function(a){return{restrict:"AC",compile:function(b){a.$$addBindingClass(b);return function(b,c,e){a.$$addBindingInfo(c,e.ngBind);c=c[0];b.$watch(e.ngBind,function(a){c.textContent=q(a)?"":a})}}}}],pe=["$interpolate","$compile",function(a,b){return{compile:function(d){b.$$addBindingClass(d);return function(c,d,f){c=a(d.attr(f.$attr.ngBindTemplate)); +b.$$addBindingInfo(d,c.expressions);d=d[0];f.$observe("ngBindTemplate",function(a){d.textContent=q(a)?"":a})}}}}],oe=["$sce","$parse","$compile",function(a,b,d){return{restrict:"A",compile:function(c,e){var f=b(e.ngBindHtml),g=b(e.ngBindHtml,function(a){return(a||"").toString()});d.$$addBindingClass(c);return function(b,c,e){d.$$addBindingInfo(c,e.ngBindHtml);b.$watch(g,function(){c.html(a.getTrustedHtml(f(b))||"")})}}}}],Me=na({restrict:"A",require:"ngModel",link:function(a,b,d,c){c.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}), +qe=lc("",!0),se=lc("Odd",0),re=lc("Even",1),te=La({compile:function(a,b){b.$set("ngCloak",u);a.removeClass("ng-cloak")}}),ue=[function(){return{restrict:"A",scope:!0,controller:"@",priority:500}}],Ic={},xg={blur:!0,focus:!0};n("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var b=va("ng-"+a);Ic[b]=["$parse","$rootScope",function(d,c){return{restrict:"A",compile:function(e,f){var g= +d(f[b],null,!0);return function(b,d){d.on(a,function(d){var e=function(){g(b,{$event:d})};xg[a]&&c.$$phase?b.$evalAsync(e):b.$apply(e)})}}}}]});var xe=["$animate",function(a){return{multiElement:!0,transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(b,d,c,e,f){var g,h,k;b.$watch(c.ngIf,function(b){b?h||f(function(b,e){h=e;b[b.length++]=X.createComment(" end ngIf: "+c.ngIf+" ");g={clone:b};a.enter(b,d.parent(),d)}):(k&&(k.remove(),k=null),h&&(h.$destroy(),h=null),g&&(k= +rb(g.clone),a.leave(k).then(function(){k=null}),g=null))})}}}],ye=["$templateRequest","$anchorScroll","$animate",function(a,b,d){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:fa.noop,compile:function(c,e){var f=e.ngInclude||e.src,g=e.onload||"",h=e.autoscroll;return function(c,e,m,n,q){var s=0,v,u,p,C=function(){u&&(u.remove(),u=null);v&&(v.$destroy(),v=null);p&&(d.leave(p).then(function(){u=null}),u=p,p=null)};c.$watch(f,function(f){var m=function(){!y(h)||h&&!c.$eval(h)|| +b()},u=++s;f?(a(f,!0).then(function(a){if(u===s){var b=c.$new();n.template=a;a=q(b,function(a){C();d.enter(a,null,e).then(m)});v=b;p=a;v.$emit("$includeContentLoaded",f);c.$eval(g)}},function(){u===s&&(C(),c.$emit("$includeContentError",f))}),c.$emit("$includeContentRequested",f)):(C(),n.template=null)})}}}}],Pe=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(b,d,c,e){/SVG/.test(d[0].toString())?(d.empty(),a(Lc(e.template,X).childNodes)(b,function(a){d.append(a)}, +{futureParentElement:d})):(d.html(e.template),a(d.contents())(b))}}}],ze=La({priority:450,compile:function(){return{pre:function(a,b,d){a.$eval(d.ngInit)}}}}),Le=function(){return{restrict:"A",priority:100,require:"ngModel",link:function(a,b,d,c){var e=b.attr(d.$attr.ngList)||", ",f="false"!==d.ngTrim,g=f?U(e):e;c.$parsers.push(function(a){if(!q(a)){var b=[];a&&n(a.split(g),function(a){a&&b.push(f?U(a):a)});return b}});c.$formatters.push(function(a){return I(a)?a.join(e):u});c.$isEmpty=function(a){return!a|| +!a.length}}}},mb="ng-valid",Jd="ng-invalid",Wa="ng-pristine",Jb="ng-dirty",Ld="ng-pending",lb=G("ngModel"),yg=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q","$interpolate",function(a,b,d,c,e,f,g,h,k,l){this.$modelValue=this.$viewValue=Number.NaN;this.$$rawModelValue=u;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;this.$touched=!1;this.$pristine=!0;this.$dirty=!1; +this.$valid=!0;this.$invalid=!1;this.$error={};this.$$success={};this.$pending=u;this.$name=l(d.name||"",!1)(a);this.$$parentForm=Ib;var m=e(d.ngModel),r=m.assign,t=m,s=r,v=null,B,p=this;this.$$setOptions=function(a){if((p.$options=a)&&a.getterSetter){var b=e(d.ngModel+"()"),f=e(d.ngModel+"($$$p)");t=function(a){var c=m(a);z(c)&&(c=b(a));return c};s=function(a,b){z(m(a))?f(a,{$$$p:p.$modelValue}):r(a,p.$modelValue)}}else if(!m.assign)throw lb("nonassign",d.ngModel,ua(c));};this.$render=x;this.$isEmpty= +function(a){return q(a)||""===a||null===a||a!==a};var C=0;Gd({ctrl:this,$element:c,set:function(a,b){a[b]=!0},unset:function(a,b){delete a[b]},$animate:f});this.$setPristine=function(){p.$dirty=!1;p.$pristine=!0;f.removeClass(c,Jb);f.addClass(c,Wa)};this.$setDirty=function(){p.$dirty=!0;p.$pristine=!1;f.removeClass(c,Wa);f.addClass(c,Jb);p.$$parentForm.$setDirty()};this.$setUntouched=function(){p.$touched=!1;p.$untouched=!0;f.setClass(c,"ng-untouched","ng-touched")};this.$setTouched=function(){p.$touched= +!0;p.$untouched=!1;f.setClass(c,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){g.cancel(v);p.$viewValue=p.$$lastCommittedViewValue;p.$render()};this.$validate=function(){if(!Q(p.$modelValue)||!isNaN(p.$modelValue)){var a=p.$$rawModelValue,b=p.$valid,c=p.$modelValue,d=p.$options&&p.$options.allowInvalid;p.$$runValidators(a,p.$$lastCommittedViewValue,function(e){d||b===e||(p.$modelValue=e?a:u,p.$modelValue!==c&&p.$$writeModelToScope())})}};this.$$runValidators=function(a,b,c){function d(){var c= +!0;n(p.$validators,function(d,e){var g=d(a,b);c=c&&g;f(e,g)});return c?!0:(n(p.$asyncValidators,function(a,b){f(b,null)}),!1)}function e(){var c=[],d=!0;n(p.$asyncValidators,function(e,g){var h=e(a,b);if(!h||!z(h.then))throw lb("$asyncValidators",h);f(g,u);c.push(h.then(function(){f(g,!0)},function(a){d=!1;f(g,!1)}))});c.length?k.all(c).then(function(){g(d)},x):g(!0)}function f(a,b){h===C&&p.$setValidity(a,b)}function g(a){h===C&&c(a)}C++;var h=C;(function(){var a=p.$$parserName||"parse";if(q(B))f(a, +null);else return B||(n(p.$validators,function(a,b){f(b,null)}),n(p.$asyncValidators,function(a,b){f(b,null)})),f(a,B),B;return!0})()?d()?e():g(!1):g(!1)};this.$commitViewValue=function(){var a=p.$viewValue;g.cancel(v);if(p.$$lastCommittedViewValue!==a||""===a&&p.$$hasNativeValidators)p.$$lastCommittedViewValue=a,p.$pristine&&this.$setDirty(),this.$$parseAndValidate()};this.$$parseAndValidate=function(){var b=p.$$lastCommittedViewValue;if(B=q(b)?u:!0)for(var c=0;ce||c.$isEmpty(b)||b.length<=e}}}}},Gc=function(){return{restrict:"A",require:"?ngModel",link:function(a,b,d,c){if(c){var e=0;d.$observe("minlength",function(a){e=ea(a)||0;c.$validate()});c.$validators.minlength=function(a,b){return c.$isEmpty(b)||b.length>=e}}}}};S.angular.bootstrap? +console.log("WARNING: Tried to load angular more than once."):(ce(),ee(fa),fa.module("ngLocale",[],["$provide",function(a){function b(a){a+="";var b=a.indexOf(".");return-1==b?0:a.length-b-1}a.value("$locale",{DATETIME_FORMATS:{AMPMS:["AM","PM"],DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),ERANAMES:["Before Christ","Anno Domini"],ERAS:["BC","AD"],FIRSTDAYOFWEEK:6,MONTH:"January February March April May June July August September October November December".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "), +SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),WEEKENDRANGE:[5,6],fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",medium:"MMM d, y h:mm:ss a",mediumDate:"MMM d, y",mediumTime:"h:mm:ss a","short":"M/d/yy h:mm a",shortDate:"M/d/yy",shortTime:"h:mm a"},NUMBER_FORMATS:{CURRENCY_SYM:"$",DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{gSize:3,lgSize:3,maxFrac:3,minFrac:0,minInt:1,negPre:"-",negSuf:"",posPre:"",posSuf:""},{gSize:3,lgSize:3,maxFrac:2,minFrac:2,minInt:1,negPre:"-\u00a4", +negSuf:"",posPre:"\u00a4",posSuf:""}]},id:"en-us",pluralCat:function(a,c){var e=a|0,f=c;u===f&&(f=Math.min(b(a),3));Math.pow(10,f);return 1==e&&0==f?"one":"other"}})}]),B(X).ready(function(){Zd(X,yc)}))})(window,document);!window.angular.$$csp().noInlineStyle&&window.angular.element(document.head).prepend(''); +//# sourceMappingURL=angular.min.js.map diff --git a/admin/static/js/app.js b/admin/static/js/app.js new file mode 100644 index 00000000..5853e29b --- /dev/null +++ b/admin/static/js/app.js @@ -0,0 +1,33 @@ +angular.module("FICApp", ["ngRoute", "ngResource"]) + .config(function($routeProvider, $locationProvider) { + $routeProvider + .when("/teams", { + controller: "TeamsListController", + templateUrl: "views/team-list.html" + }) + .when("/teams/new", { + controller: "TeamNewController", + templateUrl: "views/team-new.html" + }); + $locationProvider.html5Mode(true); + }) + .run(function($rootScope) { + $rootScope.message = "Hello Angular!"; + }); + +angular.module("FICApp") + .factory("Team", function($resource) { + return $resource("/api/teams/:id", { id: '@id' }, { + 'update': { method: "PATCH" } + }) + }); + +angular.module("FICApp") + .controller("TeamsListController", function($scope, Team, $location) { + $scope.teams = Team.query(); + $scope.fields = ["id", "name"]; + + $scope.show = function(id) { + $location.url("/teams/" + id); + }; + }); diff --git a/admin/static/js/bootstrap.min.js b/admin/static/js/bootstrap.min.js new file mode 100644 index 00000000..e79c0651 --- /dev/null +++ b/admin/static/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 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&&jdocument.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
    ',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-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.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:''}),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[a]&&(void 0===e[a+1]||b .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/admin/static/js/jquery.min.js b/admin/static/js/jquery.min.js new file mode 100644 index 00000000..6c60672f --- /dev/null +++ b/admin/static/js/jquery.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.0 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; +return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
    a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n(" From 5e74b3f7ce98b217dd487aa8a056b80cdc4562c5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 13 Oct 2016 19:52:13 +0200 Subject: [PATCH 0324/2518] [admin] Can retrieves tries rate --- admin/api_team.go | 4 ++++ libfic/team.go | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/admin/api_team.go b/admin/api_team.go index da32dee4..3c9f449f 100644 --- a/admin/api_team.go +++ b/admin/api_team.go @@ -85,6 +85,8 @@ func listTeam(args []string, body []byte) (interface{}, error) { return fic.MyJSONTeam(team, true) } else if args[1] == "wait.json" { return fic.MyJSONTeam(team, false) + } else if args[1] == "tries" { + return fic.GetTries(team, nil) } else if team != nil && args[1] == "members" { return team.GetMembers() } else if args[1] == "certificate" && team != nil { @@ -95,6 +97,8 @@ func listTeam(args []string, body []byte) (interface{}, error) { } else if len(args) == 1 { if args[0] == "teams.json" { return fic.ExportTeams() + } else if args[0] == "tries" { + return fic.GetTries(nil, nil) } else if args[0] == "nginx" { return nginxGenTeam() } else if args[0] == "binding" { diff --git a/libfic/team.go b/libfic/team.go index 10d67b72..4be647a4 100644 --- a/libfic/team.go +++ b/libfic/team.go @@ -1,6 +1,7 @@ package fic import ( + "database/sql" "fmt" "time" ) @@ -152,6 +153,61 @@ func (t Team) HasAccess(e Exercice) bool { } } +func NbTry(t *Team, e Exercice) int { + var cnt *int + + if t != nil { + DBQueryRow("SELECT COUNT(*) FROM exercice_tries WHERE id_team = ? AND id_exercice = ?", t.Id, e.Id).Scan(&cnt) + } else { + DBQueryRow("SELECT COUNT(*) FROM exercice_tries WHERE id_exercice = ?", e.Id).Scan(&cnt) + } + + if cnt == nil { + return 0 + } else { + return *cnt + } +} + +func GetTries(t *Team, e *Exercice) ([]time.Time, error) { + var rows *sql.Rows + var err error + + if t == nil { + if e == nil { + rows, err = DBQuery("SELECT time FROM exercice_tries ORDER BY time ASC") + } else { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_exercice = ? ORDER BY time ASC", e.Id) + } + } else { + if e == nil { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_team = ? ORDER BY time ASC", t.Id) + } else { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_team = ? AND id_exercice = ? ORDER BY time ASC", t.Id, e.Id) + } + } + + if err != nil { + return nil, err + } else { + defer rows.Close() + + times := make([]time.Time, 0) + for rows.Next() { + var tm time.Time + if err := rows.Scan(&tm); err != nil { + return nil, err + } + times = append(times, tm) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return times, nil + } +} + func (t Team) HasSolved(e Exercice) (bool, time.Time, int64) { var nb *int64 var tm *time.Time From 017adfb2b15d60a50dcf11102146d1a43e0f8476 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 13 Oct 2016 19:52:40 +0200 Subject: [PATCH 0325/2518] [admin] statistic generation --- admin/api_team.go | 6 +++ libfic/team.go | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/admin/api_team.go b/admin/api_team.go index 3c9f449f..a5ba9a7a 100644 --- a/admin/api_team.go +++ b/admin/api_team.go @@ -85,6 +85,12 @@ func listTeam(args []string, body []byte) (interface{}, error) { return fic.MyJSONTeam(team, true) } else if args[1] == "wait.json" { return fic.MyJSONTeam(team, false) + } else if args[1] == "stats.json" { + if team != nil { + return team.GetStats() + } else { + return fic.GetTeamsStats(nil) + } } else if args[1] == "tries" { return fic.GetTries(team, nil) } else if team != nil && args[1] == "members" { diff --git a/libfic/team.go b/libfic/team.go index 4be647a4..5db84293 100644 --- a/libfic/team.go +++ b/libfic/team.go @@ -226,6 +226,108 @@ func (t Team) HasSolved(e Exercice) (bool, time.Time, int64) { } } +func IsSolved(e Exercice) (int, time.Time) { + var nb *int + var tm *time.Time + if DBQueryRow("SELECT COUNT(id_exercice), MIN(time) FROM exercice_solved WHERE id_exercice = ?", e.Id).Scan(&nb, &tm); nb == nil || tm == nil { + return 0, time.Time{} + } else { + return *nb, *tm + } +} + +type statLine struct { + Tip string `json:"tip"` + Total int `json:"total"` + Solved int `json:"solved"` + Tried int `json:"tried"` + Tries int `json:"tries"` +} + +type teamStats struct { + Levels []statLine `json:"levels"` + Themes []statLine `json:"themes"` +} + +func (s *teamStats) GetLevel(level int) *statLine { + level -= 1 + + for len(s.Levels) <= level { + s.Levels = append(s.Levels, statLine{ + fmt.Sprintf("Level %d", (len(s.Levels) + 1)), + 0, + 0, + 0, + 0, + }) + } + + return &s.Levels[level] +} + +func (t Team) GetStats() (interface{}, error) { + return GetTeamsStats(&t) +} + +func GetTeamsStats(t *Team) (interface{}, error) { + stat := teamStats{} + + if themes, err := GetThemes(); err != nil { + return nil, err + } else { + for _, theme := range themes { + total := 0 + solved := 0 + tried := 0 + tries := 0 + + if exercices, err := theme.GetExercices(); err != nil { + return nil, err + } else { + for _, exercice := range exercices { + var lvl int + if lvl, err = exercice.GetLevel(); err != nil { + return nil, err + } + sLvl := stat.GetLevel(lvl) + + total += 1 + sLvl.Total += 1 + + if t != nil { + if b, _, _ := t.HasSolved(exercice); b { + solved += 1 + sLvl.Solved += 1 + } + } else { + if n, _ := IsSolved(exercice); n > 0 { + solved += 1 + sLvl.Solved += 1 + } + } + + try := NbTry(t, exercice) + if try > 0 { + tried += 1 + tries += try + sLvl.Tried += 1 + sLvl.Tries += try + } + } + } + + stat.Themes = append(stat.Themes, statLine{ + theme.Name, + total, + solved, + tried, + tries, + }) + } + + return stat, nil + } +} type exportedTeam struct { Name string `json:"name"` From 347f317dd9431eb13d2feb11d03b3eead829bd25 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 13 Oct 2016 19:52:54 +0200 Subject: [PATCH 0326/2518] [admin] Improve interface --- admin/static/img/epita.png | Bin 0 -> 39967 bytes admin/static/img/fic.png | Bin 0 -> 40107 bytes admin/static/img/srs.png | Bin 0 -> 29880 bytes admin/static/index.html | 33 +++- admin/static/js/app.js | 338 ++++++++++++++++++++++++++++++++++- admin/static/views/home.html | 9 + admin/static/views/team.html | 54 ++++++ 7 files changed, 421 insertions(+), 13 deletions(-) create mode 100644 admin/static/img/epita.png create mode 100644 admin/static/img/fic.png create mode 100644 admin/static/img/srs.png create mode 100644 admin/static/views/home.html create mode 100644 admin/static/views/team.html diff --git a/admin/static/img/epita.png b/admin/static/img/epita.png new file mode 100644 index 0000000000000000000000000000000000000000..e89f7181dc2b749a4d27d616d0a570e9006f765e GIT binary patch literal 39967 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 literal 0 HcmV?d00001 diff --git a/admin/static/img/fic.png b/admin/static/img/fic.png new file mode 100644 index 0000000000000000000000000000000000000000..7956bd4db0fab2c34246cc7658fb3dd0c95b47b5 GIT binary patch literal 40107 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 D5^Cq@ literal 0 HcmV?d00001 diff --git a/admin/static/img/srs.png b/admin/static/img/srs.png new file mode 100644 index 0000000000000000000000000000000000000000..82294f52864d2244b12f89e20d2cc5e6d5a76aa8 GIT binary patch literal 29880 zcmXt9V{~Lq*NrANC$=@QZQHhOJDIR!JDDWYv29IkJ9%Q;$=C0X?{?q5>(=UCtLs+P zseSg|Ct6ui3JD$$9t;c&Nk&>+6?9Dpof)vupwDN6VkyuC+Eh+T9PImlufp!~6i^GC zv$T#I7#IS^|4wkQ?A)KAMi_S)1qqm4a8w8u^pI$WEKn1njk>nGn3IEpg`+#@77R?x z)xyNx!kom*#@(7kN=8B1oXG+P42%R!MqEVQd;KEM%U?rd`MLK!cOxZdn?3|H85LcW zd0s?VSzWw-YPF7!mo1^Bq=ap`-lR6p0M$?A6e6bZVOtFLRDi2B!)^Lq%28BQWtMw} zf98Cex*#Xl@0zFc<4M=*6t#~bybcUnxYi~c zQ98Q}ywE1Q7zix3$u`o^s09KYB~UFYD%&!Fqvz4cYa9z;z7`I}MFy9gQU_4UKb5iE0F> zk0rr^+JRH|bY|VAe^2;zUw|~BuUmjkcG)A$8xWX{L?N5}8%tDNF8O!5M}tT*RA6uD z=;7$W~2G+#+hUKN8j#BeWsO$2m~C* zZzS#S;lpXZYXTtf><{QasA_OP6h-`e;58#DRMD9exA4KhI#gKA&dWv@u7Ixq#uQsy zXGbpo5eux+Ycl&%>vXrw5x0ZPP2`v|PK=I4!J$2!D=i&C#julrqsd-5_wwT>%9uC= z-uiYIv~68^^?uw<1oVQR_ZDsjJa4f8frceC<7pwnBw{L)LTr(*YD>zB zB^EHlQ6Uu0QTeHD-jqC|Jd-Qe;RH)OKH#BXk&v*$be4S|;xMw-qRq`Iz_O1XeK}e; z2%X#Y`S^)u5Rjt|x-BNs+XEq&gDUtRX2k{$ZcjKA&P#x2MjwIS5rPFMNJzC(bF#?G z4Q_T36;9R?k}$BQrUSop;?xQLN=cqsyK4P{g@Ql=t;m18e=ma=VUg#a0!a!BZSlxn zwm1`QVM#+*01yfYJ@mZb7bkpl@O0>O-3=IHQ%Xzo^JWo1x)*=JT*dOiOV8dinsEY! z1v;V62eog|m}8Bz&G3_hWI18{EV_wEMAJ0o15u0AYoY63?}OiD_c z4Ng?XSlRSOj(=1%^tlw1&)g`5DO{P*7JZ}v#u%0l8vmMC-Vl`q{G^g6l6Cp^U-s`L z>fDl1SN};%d+YzQP3L(n7*`XJ1S>ugK3igie!g-o0*H%=3;RQG~czL%;uY+Mpm0?!nH zKt$Vmp1RgH9@kQxjm8qy#f^)fv*hGn72H@zKhj=SovGyU{_RHyC1&S~D`-F>c~n+g3Krl1=!I2n5lu`;{co=5Wa;V0CVyM)6j>lL@B-pDkio#q6!0X(0_bx%FD0Uo z!DJ$Zc05?jMv$#0GwFYsjwl814c_B&7BhQxMhzqM7X9sy-Z+FL2^Qi8rzmB*Q=k+E z!-|M&(!PWDwXVO_L^EaCy=`;hH7M}w-qzC7(_8s;($+Zp(xZPG!cZFGB}lMQEWdYE zmg3;r_*>JYqPbo{xT;2;8(8qGa5S_%Rss?g4NX=TAYN=Ly4qQrn)~4njXXYjet$dN zo3a1c>3vhQagroR^g{^UG6uoz#`p8*FJ-+g2x0BE9|EkWHe>c%{)w777(6u9>g;z2 z^Uge5;-leg6>TW^T-Sra`Aa(vyW^GRY_C-;_FGL+!Ab*rwtc4T%83~wzbV7-8t}&H zfXcJ8q~s-H04VEJVw=6$q(?Fqs^qF|8C_f5xZlyyJR9ea@*KGF#03FQYxl^+f?eM4 zPnTCa!5(;rdr`za747Y>t_o^Y+y+EjApsl&Og6LQvUm|(sHnW|nZJsEz-U8KP(T$H zCMFY2Q1ow0 z$UOlt5-KNJoA`E_X;l~O+u83}M76zQQ+V;{-EMw2cL)Wn7jfY7ne1`bT-SZUM6>@+ z^QNST87!wz^jOeBALH7RZF2q83}C?or%z#_oVOo}q)p)U-nRh9eO3#VbGof?h2R;~(GZy!q+f+DSzB(Pmhr`*7orxB#;trm*6w8a7Vj9FaUYy;|t9#9c z?;h=U^h1mPs%vqYy746?-s~TG^%jKAl%o<8E70(7Xjp*a`6$y0hk`ak`g?YEHqqT{*Px!g z;zUEOr|kw;`hxZ~I&j`H1(w2}=Ea%C<^wenX~yd1AK6vVi6twW+GVIl&UC2$>^iib%Lv|J+eAG5dTc)dx}YuapPY`K`j~o{J@FJr%t0SKBpDJ z%2fVvjD=90_bV?Dg=_wzj>XeGh#y&qMMYC|aLT{iU0`YH5ftMj0r-6h4luOU6~$h) z?v9`L*KPMt)b$*lVGWocFEn)H|IPN;+E+UgAai*%du;m5Jo?uev-mx!laT&o=LV3c zVZF@Ff@Vcx;*IxbaZ!s#>P79Mx(0@h&fh(%#`aaydU+Xnd3R!7ckA;Ygu2r2P%NV_ zNEH4$U{TQ?lLpemi^-PAQTJ1~r*}}wjjuXsVkkXN2nzE;Im+?-HBRC(dBP8;+M{-A z!QEITEw{NU+M!`7_gPrOjDa`emib04Jg4r?L`tKt;K55_u|G-$?lo=xbVtgB8qG)- ze9HZsI6@^YEoj|_C^X!;j;aeKb2n!9&8!tcOlBiUeU~1r=kqcQhA)tce!=OMC^;+F z_W44C&QY&+6*xyUNO%8tUq(?GYR^TBq7HIVMRZ%j5}%%MmnPcZIQ-G5~S;w{ZpRsok9@ z_ctY6_lG$2x3621xg7b`InVVD6M;-!C-SPQ7~p9qG#FvfN36b^Bu`g7;@=@Wh`55m zBO}nVC`-i{yr%nNxLhu<(a|bZ`b}_+!+miGGyjc^Zo}T$pb8hY1v%lJ6V<5;zhvgUUBiw*I_c9%QI(K`|Q}c6<9gAXS|X?=dg7aCaMBeTymdK zTO1Pu{Xm>KcDLl@Jgu|h_M(h+Y`~puVdP*uGfi#)JG=S8zWsjU;@ErXqRFr=Eqs47 zQ0ZmXy3zhzqxFwonp{vYp&}DD@Wl}y23eh~WE7ACMnYO5hRlS%Sokn^gCPuvBN71H zOTzYjkR_pRh2d*Sud^9-B=WhzW-q$C5&DW}kcX8qIl*lw5M1r+Paa2>DO)+0R*c=R zenn~U^MVWNdS%hQAbL0noy@?_HM}gf({q4T#e_OtzJbNC%3m^yO{kBFjD%jYZ2as$ zb?>QnJ(L~&#_99D8>4>r=Fi7*;N1A#v2N)w_#Cy?+p5`w+cpoU&$RBcv=}}x@Mp#p zj^*x@dZNvGc?}9vh*{v9Xs2pbGQa>q6jpWNzFwrD6uN>*+Jgo_5{4F`VCRA+9?( zduonI72Pu|z>z7--^QZXO#LqSkzQtF3L4R4Zh{0HJv|3FN|^Je$DOp8>^Dus69BHTi>Pq3 zS0x410X53*TE>;h=5Km#@6ufS+U`WVn%-a_5O3T2Q*9i1iR2v0#Kfe^s5Qkhsyi$_ zH4IF3E-~pBo<*D_A#Zn_B6Xq%dILiu1sv^(GSx|iCKi&0ii$?OurTGW7914jhagt3 zQh#lQ$eS1{Y{QuY2y4xelmBF|;`)UCZ?^SUZ13kG4-h{GS6{uaH@_oI>gyG6qIY{% zM33MS0R$?C=H(-H@<8O%mspWi&j)rQ^cZGoR}IfTfg zpPV^UO%@Ai4ij&#d$(_444!^4`TDYi2sL%i2*mzhKlM1T50l=%70lG=;ck<1IULwI zI3DeFdvjtsprMMx7S)wmCVU4<7__S;MXR70NI`GjNo)bhl(>G9l9kqBJr8lZCO;Ss zB#9+u%pa76s5f@r0q{ghU;w`0jnmP?hl4sl7hZqvOTpY4VVK|zz0w7Qm>9R;@c`q) z28EYycwC)Z{*M>p)tgU8qJWzzGxNjfJ`Z(GTLZAN-9af?Q_QePOS`|P^~Eh^WexT9 zr%!+6GN!+UAgcgEU)=k<{bA4Rm(^SxoNMko)x3q58yfT{s86HoYU@gxa$;iC6Z(D= zJo+5(5RRRPBAfw1iP)V8LW1V*C!v9SSZOz?Y%;WHLzLQZ2wbKO|1zg|<0Roq=7hDi zx%c+avEf$0;**0x1kegUnLoud!vbonK>Rlf82k3tJ~0X;U!$P=giK@scT-p z@%?Dq0@t4gQ|!zbfu=_CV9Lhl7fFzXI+Oz=mvnCsw{#>6>U83SgLC<~8tD96QFWb( zYVa<8UYsmJz2vPP`uFA542fkfNLi`c=v!U|1W8qmjK2H!hhq!=GdIEe)(d|8dcPh` zO-~m*b#5|L)mWmb*6+v|ch!TD+tzq=ku9`kHc6t21ke?B6i3X5X{_oJhzJ$M5dSEt zBBy2!A;O&tm`AUS6jowQ6=Qk>oixlWQSmV>wX+1dYU zs;dM1=ZYnsA-}%U`h3r;TZ?UNZ4DbX^q6QEs}IhH{hE%TaY*29*-95(pmG_0{e0lw zWHSG+Wfm8LVpKwzoh1H&Xs!ZCjP#?DBXx6=A08fFT25}zoYmyl&tE?grB$ERd_sgl z9f_Jb9&~JNblMSYaoSOok%1!u;PfgL{T)*r`;r`&y`aJS*Dq6);qf!xm*3Io7p4>e zbuAB-u+%IMVnw5^ed9F+93wfsrhM*Z!LnwKs)50MEu&t`M`Kyp$a^omc5UxhNAusm zr;nifdpTsyM%z=tspShaDJ|7`8QwEY9EefrJ1}?wR@0w?tg$CQ5kNVQ!qUH~3A2|Q z6LTx8l9ls~xLXV`nT00eG{y3IVV*0&?6M*tU3Qs?Q*)!m1om>3j+lc15_oUu)|K&f zKCkQ(Xx23|36KY}CTqBZlC>fld47C>euD!(BL zbXXD^x#Ta~MeC~NSw|QpuaKGtWm=Fqa#bt>#9HIPV|BR*O=WiAoA%+ z&UEUKit}F@^Fs<-GipqDKm4{UXKn(wp7*OxN3Gbc@vh#_rwz%@tuK26gUdsUsPiTb zxu@tOY_F(;myBSb8xEd3Ym$rQG=FEXikaK&DG39AE*rJtKCrTejE@h$WNy~t*EhAu z((CKxI|g|P87wrO|FkOrJ~R~m%UBzQs$dJJa!FWR9P?l#-U>804<~aavFlg-yU+Bn;4W}fWW|)5S73%-!NI`K-w)`ca~#wVTJJ%;=5*(H;n>P! zld@RJ6lEvw9fN=V{L%ZS4_PW#D(GEaS=lyFF)Xh(^b}TKX*T6XRu>x0M~8w%#kQsD z{gri_axbHRLe9#XZ88|?vh8y`SEn@v@ zl(Z>#`xGJ*n~<=(v#QGeIS8xHFz_|4($3C~sJhZ=KA_v1`A~y#AowaXGLN@{cS98% zlht>K)zqHzHR3irG8>oG`)3NZQkm0E&&lH(Q!pEhLv1c&?c;-+TwGBiCML$ErKy?zr3H2#&$XSYZ(zVvzO;?k?!Lz~j?9Jd z$qc69x1ga;LHd)QA!VXzoR1-hjsQyBw|Tx>ysI1^>?p0Nyv@Xi{mLDCk(74<4h?wyP%ALC-J7N{ziqPCm#DT%V4(SY|4QLEeRD66nOH1tNXqnZ^>XZ1usy$x& zDMx<8Kjh1M<^3L}fO6P%eT_qf0psM;ybW@3mBk+3ysM3lj*ho)731#julH_1YKG9E zE01di!@9)Swy%OD_6LM=GaHL<_vGSz?ATPSgi~TBuLm6lwIT%%Py5CNO_+$1sVW0K zwv%Le3N9-{LD>;iP4^XgBqIIMmY3jBgw?SLEB=X4;jR|UNjg{uGbPZ!bl@-UIbPx%eGGjqzLcCCo6qa3KA#^aDJd!SVTrBnS^IgyD5^9f{`R+3 zB^_XNDmx9|#@ha<0OcdAciTlsNzj8B<>TN7r{n5K!1K;X1q-Cl@zl)gOUbZ&7H{N@ z^LbFXyFmK4th6) zGX!w4k&&7DNJvCn3PDu0?ga9I(p4cXH8r)iK!d+6K}yw$p{-~_Vdb`7Gyh>xu$nC^ z+qYmtqYzD6WEezJ$O!RzMWkB zC%aycU_K6OSMF91YWJ)i4r3}US)HW?uV?fosfn520HKxl5E2XQpp{6=z))Is0Sg@_ z?DV9fcPOdSoFaT~PA}0R&5nem7po>dtlgZsdZS*ua^9j_y|cWyNK>x2v+&f{v2`T} z+6Jb1>uPm38mn~)kOFy@&jZg2>1Y%!?$#o>4Uk6w#50pwY)WH}wiQkTM>ZzMUjh6d zeX*%&8U)?q3X!x>KV6vy1(!qe5yBZt^LR~>ZL!FF# z@OSj@qvoLA83V5!X^8;Zf}k#l-kq6Q6G(5j?Oqz@%A>OLtKsAOPe90oF}w3&nii}1 zKV{a&WLmsMEd6z*;L0uYxzPW@B88*!8)AGtFBuk0&CK8s5d3Ni3rRk-erU?cO}KGz zaHI!x+BM&em-u6q(^jt=lxFeV#^GgzRV`%l`@ok-#$P0E3jHzs2m#|*dJHbCaN?wO zvGKndE7x}$-pLfYZY0)ewjm_Bd565%(V9=+8{Q*hrGwB}DO-+*CKU4TP08KHeUP8B zd>oIz*jX7NM8@R}Zg&!#+?Uw7`4`4~C#1sLXYuQo+mXCvJf6bLr1#yMMDfDH9>jv8 z>7-W~DX$z;h;UTG6h3lHnPho-Vqzi=F79iq5t8=(@l0=VM~APzm_cRB={xJ(6(nZ) z6tFcde8`!qKrNi1G7g_Fe{V3V0NbI^29K!~pU|?V!xNg={|<41O6h3hx_7V4?#k+I zac#2T8Mh^U`QTKG)Y{Q;&&f+bTHKs_im`fei7P21Lq_^HrS2GguxekwypU*vwFE`uSnmRg;3|lwGxQvJ?oO6?C z6y-i~6U&!BR7{l6RKZ-nnfQs6MuVp_eXySeZeTzW+1lRT@~aD=-M-I9;JG5B<*{Y3 zer?yRn+4hf!=RDLYDq%=bH8T+4;DInLd(;;J|TVdDH>hv{na14#ec$T(mOS??yxl{b29 zC>EEH1wtpfdU`4l z@YU5(^;~p9qC)Oe_^|6bx-g68=9-KLoXXBxNA-O^Q6!5Wk-n%{J?WY}nFAuTpxh$^EvyS!_TOEw@d{+FguWMjk zFBe@cGKDmYE6W(zjuL=0g$=K}6LRK8vkk%JnzcS+r%&oerjC%w$$YS((NX9ANt;Q( z>mTWiL4egZ8pobJ!Qw%L_P239?e9Tsb&X5Y3$G}Oa|W!1g@vqNCJ+LCPv$o_-sWN4 zA&b0*j38R-lA<*{e5SVHX(LZuLP8rI1LJ$s0eJH-iM*AYpqdsxkUMUr+I{`6KakLs zJ)e$)F-Ar$wr;~Z z?A^ovNO=s+7HG@;{1JVEN* zKvnkb>j#5QSN7>b&7QLjkDO+ggrPDW+#FR>i^GOO!GJwzflfa;bo!hWOtoh?|GyW2 zdG8UX@%k^kpH~Jto+T+gbsiWzG-4(!^(Mh^Q~|$~xcH09CHHa-@AU_*{puZUZI`c* zViaIZjmZKO?EK#^p>q|rU`RR^komqp?oZYlsb2$plh+q!DG!;b_3?=wZ(|gpyJ4>; zKRlO^8TmKyKw-zJDrVtIcjg)tr7AB8+_c)8r^Ueb>zIY!MQ#{j`Gy zo=ZzO_13SIo93td2*? zNO|#Z^Zuj@JD(UMF)}(9mz2C=o*78mb7WoJjGau^XW@)PxPZ)JLf z^u-qJ2WDZS$cm(UOy&nDNTm+U{Lu6}K7HgJ7!cELb|nlz@Jq@38C7QEe|Ky8GP{!dqG!8DeBa@Qr^GjpdbK6u;G+41OmKn<77 zvC&5q@B3@|HzNaPVuy{5w_%hp@N9YhaJmy+)cvAYD@!0{;fW#4L8)`TRrPeFC*>=L zq5T`Zg`T|-2$-E!X23>xf4UNzf32W%bKU>dj}f)_JHdUw&<3`4rSfrFj?J%IFi1>n z5WRKdQozAD9+&M&zr6A>l4IxMPgki9)L>0mv{{<*R~Ru&R*Y;oM>wq&&fZfKtKBjK zD=TYuym8D6YOq4V+^X9!1QYJ041>d2-Atu|-YFV=C{1z1&o z@;4w_eb3*nFU2dzlp@Qz% z4z{-B;|r!9Rv$s&OOH)`rP)>qfiSn`$~d7u9yr(js?WosrDTLavTTsXiY zt5}AIU$}XP*z`Uuv0rZkxRu8jm-@3fK4X_D5^gRhD)PBCx?#W}tgyJB{Mz5&4@@%f zAUo(TDvGYf4wUmy~_qSjnO89@Apv~HAPaAcqsfI zIAjB&uu!Q+{4DDmEbiJY0FVj{4Ry|WwYvvnbfV4ZISQ3Z5j`*`1j+oD0nxD^myb`Y9e-MFQOFpnNr?BA)iV0<2fe;|d z57aLvaceJ`%8qr(<-pdoeL;yhLLsP>wU-oQ`)@u}*j;CCo$o=;{QP^Tn$9D|X@Vf0 z_AIm0G{NL(Gp57mjPGbIqb#Y{q-^BVQX9M({%_&Y$ki*;sqzA@q_q{JMakKoJM79H z!m-2^^IEDuyzzq80rPr#tk*q?((Uq8OwgsL~*C`~OV94U;WcaRN&Y94*0&!pSu zD5BGQZ_S7QWA+?MS*PCJVbq7UAyInjHx=)QsG}ozbaeCg=;D#6-FHP?=$ z~)rpicjh3&claR z^=}*1{rVBC97|IJ+h_fzECm>#`~;`(siaT0&N$@4d6oGuu&ShGJTQ*7hMJQzMyjAQ z3ymDQ!T8Jc>v0y}S~^@7`V2oiv8g3j-DD3N8tF2kShzqiprfMfiq5k$1t6p^|C=e= zgdCnFYd!d3sDzpI^Me)>^Fa_9Y@_vhFGZQY5!x=5w7fRpSvWZ( z_xDYoF4p>sR)*Fd9(gy3oMw?z>b0w2F@*u)k^v?0Bha1c znFN2GtgQ)hGBTduuC_XtQh=hpJ5G1r{Kp(zYkz6%&@XN480#x1g{}j$6of7gm|F$< zcdq?IQcEeIF%MbI&7C|Qgu=_3s|ix($)ckXC&eMMG)Orhecd}YMDWXoab-)IdlSfHJ=)qwY7M6Lyy0&k3 zps<^pTx#`j2?w8ke|!lZ8d?$J$qs(y()c}d@654L4YmVEe_IUPdoil)O z@ZVej$aVDJ@gezyYikGH`T_)_-Wy|0a2Oi-ds6az3xCjV!OSner(x=k1jAahq2K+4 z|JfhYd8EV6@ITV=bhGi**kw!l`!k>jdGdw59WKnS4=Jqd#BN<(EQga{(y@?|CfF=U znQ>-UI63ZBa|vEx-?Xf-@bF|!8tRn(8Aiurf*Dha7wAN0^K=(d#{;Q?qO}VcH}v7U zV%ja{kfIAE#blxFr2vAO!E3d8U9nML{`?B!AL%p4IdikK;u;avVca+SW@is*m?+a^ zbjvXyn*9O9&8Os}%@jx2X*aq`jS5SMMMGT|Miiq^rl2x-S9Gp@cQIr3rR+}M0 z5FYDiO(3Y*k5ds#@H>jm-wFK7R*|30mT_`oJwKlUP!r0^63FDSgI7tnZn57P4t+JM z^I1SP^#4M_4tV7_JX{iLx8`1AeFwQSV(LwY{@u^?Y+P2J=3dyVs`(}6I)?7beo5O9 z%FwcO-OXccI!{PcX+J?K#B(AORP0tt?944%Q*-bzc~2LMn^h8m*eL`Q0NBsxl0MgV z{o@V+qH$!7n5RWCyuk3%+r!awWh|sTWd1fA`#Ll6LL2j2Zuji z*93@?kXr`fs8#y)3Eh-`5DC_!M8Y;8@O$;!LWu+xcs-|c6I2jx=Aw*l$E0GjT>2N8 zY{>W)Ak@m^DFsR41+b6!pPU-pd|B;Zggq}o{7A;O?9RtnuGciu=6fr3rqDMV(9TwA z;@fKxJH~S0zddQu{eMMxoDS=A)h+sthDInlErDuhj0X8AOjxs6vg8+(;HxO*(#==xTg(CE!e*5vL$^?OORMXLSoA@h=A{a zDBwSdVumFBulJHmopw`5P=*0Ak}Bb=8!_qkGjeTCT-UZGR$auUAWJJ=8xB!Ql9H|l z-M~J2C}3hAx(zC1usLnBZMt1gabHw_oEK@eUp;^CCT9h4JJ>92kF2dsL&->}825iL zcQi9w=uojW;(*wG@nIRlJqW>CK-l|)cDE<~;}dk>OgJ2*_v>)4nyWd|alQ~-9ZaL} zL~6zo`2?@1s3=tdrnX|ao2Z)`Tbc%^0=z6eR$9}8`1r&GoHab-6jM6GYr2-vCsgZb z6vyO13*)=BwY7*?iIyZ;gCZqAL-OL{qN7%rC@iPb_SgzNS8`g;w2s;a#ZCSe%xb$C z%4ZDx?72s|d<-3M{KKcfWxMH|=Xi5$GLz?(dhH=M*WJA#E<9nY^BK~(K2t_M#%kn8 ziq6|3--S?DC<_M6&EWbLgMQn7lklA3^A{w%%#5_S3Z`c5=IZ5Hol=3IxVU&yw&f{_ zWVJ~VNNZHKG-69r67-Gneb?>L<;`F*i@F7Yn1-9!;W$EpJ;lr^@=*2liU3?mb0Ocz>ayx%|HU$;08SWe`;Hxz)%*0cx3RJHCqr2g7bIW@B zag9{_OL9&ow++SfrWd)U-HFmN4-W@;-lnJgW=r*Z$Ey9MEi-G-}73GQ=d*kOT$SvEU@;`q}keZWo@!}PCJZC!IsEWx-yie0$>ccbJF4JM! zZr^&7^4Owdr!<14cI{M?_Ys2SdZbPT@)FI#RawZPXNWO2UB|w@|*f5YzupmP);O&D> z^1Y?HQ|IoG*VkecUYlWv zGBYenWNg)eC_Cr!UpT5=e4j0c%T*i;$n=?&S8;Q>kD3FE=hf~=|zDOzp0$wbU+J}G|SPV3)o%Lan|@Hq0l@m@P`5K4W3P+664 z!^IV@#FUi#%8GucB@^z_|`bzLk>iPPV>rF(F98k^$<{0qFom?enWknd)Qj^klkvkVI9Z^tmhW6I8>8WA2o6cHII=>eX;aC&k6==-O`*KZU~JMaS&+rsTA zm6U>dWOq0o2OmCASgNnq#LknH6pcjKQWG77kS{KB9kJFN&L&3hm3kFoJ0qlsx=W^T z{w%OKD;t?s)wkXLDx?979&bvxxa=?`At@+KeSBU~X9f&!`QLA03m>H8GaoLkd`qa# zs}LUnG+F}^?QG9hTP%bemnMP(+d(n>bLdQNe_6;-rm{9&Nl;(W$7hLFspIJ@=hrPF ziLjUf!uvDfnP!>MZ_WXBGBSe3_V|ygipoC~G#OTg9VsCALna69{_~awTrkjy13^$X zhDc0Gy^C0=1)Ey4G7Y4i4lwnI0!CA6ZDZ7pE>C{XtK23TB@V~8P8Rp{WF1N3|B0eo z?d}Z!d`B*^4ID?|Dpp0Zrl62e*4UEQ)YRmPxoBD8GJFsI6T8B4zbS)AC>Z>-T6A(E z?doeaUuVMDSlj#ifr!=s`cKmXEa;0~nzgIpMjDApW7m0#+TJu?ABW&q-Oqrbk>L-D z!u9Lt|IEHEudfERA9(ZqZVN{LuA7CBhVM>}mHdvEw%p3D_P;%Kb!>aRTgY|~gT{d{ z)OAoqPA8z^E4OMLX?#3eioM+MGDgaTX<=D-8Erl&Lm=sA$f{2uX@iV~eQI|_SFzj?E}zTLlf0vQUQ zPZZEWFl+d}_9Jg?Wolnq2fw0Nj9mBy4he~pjI0YkqS^SpW$WYp4+=|;$L8a6&aa>D zgbYETJ_@iVkByy7?UG6u*k{JX*iPs9GSa6z2&=#mZBV$p7!yvUSM87B2Pvt$|EJ{H zg9_nSnWyL21)$FNkAE3*7W}-Ughr<0r|e|lWC97M*a2uIAt|LyKAB=g#wj)miq z+1OiK?&OPY*;;}K{0^m>P>Vu4U3Yc{jXR0uloqP%?E5D|a(`xH|R;2WO z=P)<9PjdYmih8h0=1AnJ)Sl|m>8Gz(!nY3p2+TzxXC(({Yz95sO?KH6ARGmZ?Lo$$ zAfm&`pdtRum8zUtOaE1EMS$Gd9oBg^EghMtj3Ai;u2W9V%Uev2iAyqMN=nC>`xW-) z9zNCdw-Cye^yX0nh9U1>Eia*;phK4ODleOw znpy%9=djszL)lXXf_nnIA0J^>oBf1pyVwgF8hlwB(RrRjU7FSj{Clh^%XURh7^ghV z^AtgDS!55&OAvj#eCc^k$jR(rRpY+Zxc59@=hh4I4dh2J#MJRzE^4$kSR5Go%Yq@r zuf9lk88XAcZ4rAdRcfI`0vO8X3`ez$YQ$Aik+E#pab@IU%M0spii*-pCLR!+%9=`v zbO;E$TDs#yBjmOz{w_c-U`POnR*lAo8y!h$14$+_0!KelK10aUc36(H{AA!D?$p=U zzTynCY;pspe}WzLG!zal^I~~W%AiYp-hsv6HRyt5@{XkxG;~u^c6Lm=%pbIwB~-z& zl~yzV^>iLP?=AM;yiFM0g6w@D2}5c#XofyqA`@;di#MUprlQqs_M9@TKXD$s>h0}~ zqF|=d$-#r15CdYTM`a*5X*iba_S37g?NN#CcMQ_r?lzwL$?WX!=;q=Ico&!Ytt)%z z%)l=wRyDWG_dAHqnvyY4O&w*o6l=E|0D7nU{z=Myts%p%MkvEe@CAol5^Jwt3XHh6 z_migGr#k^b$1x}Y2;~1-MbLM>RX`*b42}U3Yu|rH>ANgRh)YIz>Dc5a5MrPaDJm*5 zgK;`;47FBr714~-?vyyVMM!E`5K4^$I}`|8R+t3^iBdqG#+{>exFwynCLjFDjBAQQ zA}m%`-lq$}$$rSghjCei0cGP>z9fo}IqQqxvZ$m#~Pz`E6|#YTLg-RdsRse}f15KP@iSJnA-@Mb*{aH(2~eNLZNU z2xu$&&mRfB3S&Y;i)jcSae_zjNl=wR$wouJ@$VnAub*Gm5^yK_$VNCNYf50T{ldLH zYq>lYG#JzGd;8uXmb8&lu=efjY2CpQP=L$-Za>L7Q^nP<%(1JTJ`4{Z8$`~Q+) zjLa|E_WBhwPPFuA>*M7X*d2QhB9Tw;Pe%Hi$6mo~ATEBY8Rj#6AfVT3P+%cu4 z;Y>4^3IC?Dv!MfD0%0KjOcWO2Y+#rjV+BFg zUfE2-pK1iG)89v(TNuPk!vLOD%X{Lb~@m3xWUi1|F*>qSwxZv3R5oeE4H)UM0> z?5TV5oHZh3BBlh~9J|7uFMvn~heY_cPai~pGw5+$?`^gA8qegbzCBEtjPO{w-816M zmsml7W6CEJ$;{85KK?{}Gh*z|T*4bq+zVhaKDz1^3{(Y!C$+Y5JiO{8Ix3DWzq_+T z0qO6bC690Qmqxu!ZTgN!z4y4rWP)V*AhOS-o`87x&1~45H8GVSDtu^!v2(S}#HuxP z$G!zr{MoGt-*6Oq285Ob5cXB=D3Fy%k&*m6%ahj@r&(H37_D%H1B^y7oKxf};=mWG zVJ<;s!@evr;U?430smL|@^Y2K_>UJ(hnhS*e9oLgfE>GtQ*6e1u>?p*RT6E~S^9^X z94=(^@@sAe7t#02cV+6~GG~L*bWbS2vZ&1FV%;a$sn-d?kH>8sHU{Ruf)@2ui>&Z) z>jd@1qT)K!S6xt@h5{%NYh7exsG2%jKK;{D5{UM~k5}9KfyJAbUnU6yW)X!)BhZFk zB4Nymf8*Uv$kX@<{-aw&nm2D6wopxD2@JOP`h-qG^5~`r4}@`)SDaJhSCnt|%kI*6 zRZ}n$lR)EC0gUXgc-Mfgy>AZzh3hCSx7z`Fl+PE$rp%v${=0B%_umv1AWCMfd6aN8SX;Zf`q1aYn{+M!?kS=k_tsppChvpJwLmw{LzdH0z%mFVvP009;ZuSOH= zW`T>5SO>m@Cv&IyauxFjDWWK>2`qYPb{xoqV>{}rELv8yoj}aY$}8@iq3th<`22Bi zYpydB_U+w%+330RB7Vw7fVYXfSYfX`vtV$>4g=s>FNFXT?On!mL z*-IuWQkLkPawD<1z8(R=1w;) zpeQLVF18IItWU(zN@OT#DT@sW4rtlIx=CQ+vm*t8Z5{&@n8>W}&49I*TQI8vuI#2b zil^(prBzM&JWh{OZx2&_;UvMm?Zl_>jK`=GSn(4YM5?MjP_bE3wM))1hFCnO|V z*UhtEZ%V9$4OKLKEf3)R+9#c`6WC!QDPj3iXju5SUOw|*^dHDskYoh@ zP)rjEK4rWp0T7A5c)%1*7Vjezo>%85;(~-ZR@2puiiu&63qSnbz&yrU43hQ21Uf|W zR^Xt;{8_zd1%qJNf&$rm!@l?!yPUO6Ki?SrIfHOPPS}l7|5K{swZ!WI%RjK;Kf}`R2I;P)vh{ccVR;lTX-hOhZS3EJLc*8MSOlEE%Ul z*qJi6D6HXwFvLAiwxq+W5>@s$8wfN3>sBmB2(G}3O9G$}&P9zKCz!ssd}{B3? zIU`5LPLHpFfi&jVF>ygrF}gaXx`uE%1%-@g?f-Rjj^S~AT@-H`+iYyxwi?^EZM3m% ztFh5IY0#i?V>iac#w2;~|9zf(%a^$`_nfoO+H3vx^5Y8I@#CxR%YmMt7%I6lI*6Ek%PxWLKA{*k>!#kSm4HYfr{L{&(o$b>^_f!>#LQ+rRBv3CtsRoSm` zGBhzA2K6hCQ&yPYO=Qz4#}SK`LHFk+wDi=e#G2~5EoMA*Ua*)WsG~>7S5pz^t(*c) z?Ve~zFjs!!S(AQ@OHol8swx)9x>{F$y+Ejwc)hIoZ)m{FwOW1O4S56#gJ5;!+tm!= zM9WrZ=iAHu;Wf?WZ#%Zze-tw}?fpFyx~Zdp)^Oi@w7#$~NmB4Ez+I6VZ7zKkc@(@z zA>;T9x2UTRf&+&VD*}}SFP8Ui*rj_j*#neBptw2TWUmixK27-RK)WEiDB30`iZ)~! zL?*;XX)M z3Q6>)v>aK?!VX?c>NqI4f433np8SL;H2C=VLgaNCnwCcikgculu2Y`4o`|6yPH8ho z6KKW@qdl*#Uvzw5et!{$eb8#MxF)#B<2x_=G|ScS{#&GPYOPH`?x)`K zqd!Y>Udmms*pF%gO-)ZxIBX8x@y^jnDuLCxtqaKvi?XZYr7SUBv*jgvptC#+1&s_X zhDJw_rmUpIpDW?t?Smm1M-92-qVsdr0p-)2SySuDy&vC}U4oXK^&`!wkTRh1 z_risgrnCS`3I(GetHjeLl*rIVN^}(If>i?RGVKN=PR-J`MJfGQSpV2et=!zrb^2$& zMXi876~-?kX6!}Fv0>t5&{49rU@%y^bdHjWN>?R%KOFM-?la~z;Rvu~k6rxDJN5FB zT>MJmazu4fn%XbCIMkIa07 z`6>z;0@ouzZixFv9FK-clMwd(KDKseqB^DxP?>hm&@TaO#cZ&x#`*<=xdOz~TIcyI@k+9l0UdK0==ln<8I1y%I zezai-+*_<$R6AfZ012<@t+U~~19r;`HuSpr6IliM^6F+h|J=~YS_zrjWzgQcfACjN zOA2d60)Mqwx^Z?YSb8+JpkV*pj2Oypzu+^z{mReb503{78T`Z3+f8j zYfI}Edl@>VhFsfa!vUekZ32+THs)v=RO)Q!x&-!`-l6q$PpM5Mx#RbZd}H= z*?!x|@91u)R<5)=Yl~R;#RWas&y+j-?e%tjdwb^JKscaDkd0$#Vtdx=_C_m$9%na> z|Gjk@mq^TXTF37_vIr_zS*@`l$ED&^QE9gF=FTSnI&PA{6LGaj91*s+2a&&hA%Yk_ zp3BHf`Q_eXB%|tyMDRBjRNtQk0f~_9Ittu+_}{P2Kyy!~VF^NfROq@HZ7#e9bI3YY zEu9ML*=ZTcMKzCnX3>=;v~GLK73?OW#s~=PfM7c4!2NgauabQYQ43XxGvAvNr_}J} zAjf7bt=qrV8DkD+Ogs> z3K*E3<4W~rWD_Yn##3ZO5Fk_|5v-7ChNn;bR8=#OvK<$r|8v@?qqvW4VKONCja4!J z9B)z@Xfpv;%E3pRxt#LkB(#}5RfNR<>*!Ohm81wZ{;-5knPW#55 z+8j^&pEu)?vARuO(0o;ISwSG>r}LJ_(V&W^;%r3bEb*OheQbd@HjZIjiWFR2;WPzZ ziGc7XuddFJN*xb^DZ!ptcH5CsS0XUT@BcWF`8r!%s$ED}-*-_$j4A?{`}Po@uDmMe zEFj~h^}m?U;7v}o8;xYSLhAO|2$_^`URG3BCrrlO>7*3KDERp`sl8Hn~j_AU9zdn?4Sl0-Vxgj@;!_kU`3S{R>uZt={>8-9PDT#K) zyrpG`{ZvCkY&6g5_c(qO-)?oi(SqOexOG%%)5^(5$5LZ9_OFCFNiKm2oRr zbExaN$qc?4Yq$`$Wlh75(ClwIV}z%KNgAti)4dh>4osLvtd?$5s0?#tMiu4g7w?0dIic z{!aH#JMgWD6};-LI%*5E>FgV1vQTjPnKP#G&$I^88^H?9BC}b zyo~npgJ&cXzjsI?dT;x?Cw{Goi9xX7i(|4Ys;WdH{F^ygVgR(&iL{v4V>Z_Zj=A)o zm%C@w)zrotNS-lKlwqxqk{P2murxH$1B8u<(2ik%V=Q1hkI&tXQS0p&R7+)=AeLbSzKV)Tp zfI2g2wYtl6JgXj1ln}C|^>Dr}BPJ%62;)TojY_VodtzZ#&UQUH*CgtoYfFVWBN!St z$tfyYf!WU``+9&|^R&MGJ}`v(k@uy-aB60edUew893*ZX;j+NLs-#*oGFyDm}C+SDQ0qcAwO(`Kw=Xnj^Xd6A?0^c zG;*hmo!tZW2pRYk)E}(4>>p+Lt&N>|T3#tArCgeULzsH1J;m^tKDnLA6XRB zD#c#`IppXprGtVzB|SZE{d@#;9~7uz0z}7a73Ac|cv$3ARLyWxRq(v6$R?J-sb?El zlKJ9#dh}nGE}>H@8$3-|;g6w-+U}Xc#FIJWa&p$3P~GT9hoh|oi+n=ahr4GmCEhfYb0$ z*BpYRCd2t%scTfH@bpxV+i@kHN@)g>MR>0C7SuBhKtNphi8vQt%(0Q9$8mz5XOX;! zb;dFojLi?U2#2b(Ykz#ATts=v;?{>xP^5#Q71@q1RA17L;U zI5noS(r)BL^<$m(qBGOyRN#Xj-j&s@$py*Zewz(mA`TCd!OOWub$Q)2f3N%U6`zkg zakJZdu0r`z-Dnui7A}1#ex7A7T=!%D#M%fZL^auwR4G$w``uUYVOSyP{@4&8uB_ol zQbjjp1WDNGtAW;?0x_Mw|(2SJx%7-q&(F0q;e4X{d!LP6|Rba?K`wp(S39Am?uu z>Vla@LDc>a8LG|Q#1Jd3#cAV5$R#~JAttO*s}90c@ZSs}+u*KNoG(U97Fryxd7vOM zN|Y#hSn}zP68BE+nW=?@+VpE%s+$vt^dH^Va|fCO|}r~JM8Ru%#w$& z?Go1~2A>)5IZRnOE_1d@?Y(7fS<36$!q;-Vu;>Q2E9q6#7h_nkP8wP~e(R~#(kbvc zBV`&1hfgqff3q(1gM@ss2~z>`w4tKElv(i%uIhgM1>N6ru>UQXo>sp|MUiN2P2f7Z7U;WhxTu%v#=BwSq53~(cw^3fYfAUIEPC=`*B==#}fvuSo{ct&9E~2w`(BhnHZBB;P!{$PPx4b!Co2fe{dK8?1JA zp*LP*1zetmve-(Cl9Tgf#Y?1YT6mx(Rokzx{5?7H#fw$s)ZEk@-I~J}hC8xytOmzk z7X9gtQ{@_jeFa};W1q@^S_nn>#fM73E4`SO9s{HLGiVvhybVYIsKimqRe*Wp=s==w z^5mVqx@;<*h)rnm*z)X`@BU(~1xf;zDe?dlF{l^5WEFzoGfUqUx4pKraJ3i)Lin@8 z7Q0ifE3)}$d=!6RIB{B@im|b>r6tw9r&o^?)l!QKxa_;^oWYz@{#WV4!P^n{M?>%H z#S~;bRvAaJY@=Qdu6(0kpnE19sDN#R+NUR z;ljaV&4SA(9@W4@*f;cQ&2b8kk55oC@Q9(InIjuXNn)fj3O<2s_YZ#Tj(*KzWoL)@ zoVEAwd!!S&ELx(#*pi~=@jdzLsu}!s~J1~@wUiEnk<7DnoheF zVmC^flu=J*mD8ZCqa$Lbu?G$I0jxQM8y%ynp56c;SCE*~oY@|p{9NMpI$sep4~4YW zM`NSdHO9RV!6H)zTvT_!8r&8M^5^8V{35Q5q4Ha-9kfyog+n7F&3Aff5S^t zvpq92(;j%1N|Bl+v!4!Alk%ht9AptjMCAHB#3tY;RV1QSpexduT==mo@091o%pw@f zlHOMHbmFMZVLFLMsaRe-B4;0)*z5oJcVPh>+DY7J?~2Q;Bkid9by(RNZG2`%z{1#0 zh=GXM@82UH+h~u72i-Qm&h})Xk&n#-NwTVk;cC=#_mNfRR*V15! zkI&tkTS2Y<#1Q{!0w|#aSFVM9d=?g?rA5SgD4H|IMt+%8U%5G~A2KI{KoT%WXG7;4 z^?S-J;833-8$WCdsh3(#0a~HixavPZLnz;cHejtxYgsYpe$t+H&JL?rOqrDw9WE@1 z@<(o;Cp(MS@{HhXcfVUv2RBabxrPyYORCRlc6Mv4=cWDeRI1qDFP`%9DGdGE?C?0LUbMfB%%@Hbv)E+1 z)^L#lyc+Z2cmI!H3@pKLG11V7%jUySa2jcxdv=*Ct+tpyan@~9_40G?GBZEqJbf|I zN28@34LOFS6@FA+J_AizlGUa_mh*EWnPEC*te)E=rk$DKtWb!+GJ!f;plZkIe?CV- z(Fpi`X(a^QUF6$ehkxq=Ogmw!rK;*`;Hyjh`GE67-Gb7^U$ z|Kp8?;B=jKYfm&?3d;fkcK@H-li9Bmuy*42gm0*Pcqa1^fyr8ZHc{kQ$kW(vx2d*G zZGF#EJll+X8M;7S)%&>RKk&t=V~#fJPkNo>`Add$VtMuOS$&u!;=HxNB=S7-;m`-O z9Qv)1xtN+{@xvQ%`1x(Bo+NdZ3&4Jc z*m_>35q$Yq=+X%p2G4H0Yg6z%6e#$<-&Y#ERKQr4OwBm8Nq<%08 zaN6Ma&g1ycA=R#pRq#}_tY#j@F|nus%7qrVGovCfE6z9S0VjBQYIe4gmKKb!?|FQE&n1{!K-7R?b+?HQ7a`tr{Q`iCqx+izPNczVco6>)g0=tC?%0H%Nib9l z#THjqhBrFhZ5Jlhn0l+bH{x4I=0b!&cjOyMCo=8!RAB;JYNo6A7$p_88Rv(&Y?B_C%htfg9G31K+pNbiNko143g##u2CoP-S{2()$ZM@tc#Ah=buA!r=^0bZvg>r47ea%HfV>R8Kn9;sI zC_$!;k@uBi0vejrd7K#7*{;?oR>NZhHaXu=(Dhq#rEc4k^YX?*pbK|Ac!MOT@SD?lCFk38okYlDF>h3r&9Pdj51+i>w)%>2?krn7IrH(PZE$PHgUG zppDCA{nRVA0KA(IXKQVsmc8r=@6YxNm8us#Jw2;1p=7)VgWqWhcj>Xw8r%J&6M1Ct zA*AU4*x|F+qPmu(H)J^NuU5QAi|8G(kT>7wy8ZdOe)Sp{z<)UpSFD3;du^U#6dipH zET%V|y9k|R_|3sqf|5@>A7^Sn>vK$X1672v2uiG|xj6k;K zL5P5A|1DugcuRqm767acWEwMHjO1ULLuelfzC27EjpQ;@Nk-MTndCS1N2f;Kw)cP3 zj}EcYU~1af+L~VPvd}UynXVsN1u!2pPT|1ASY$A+%1fAk;fGStv8`-jGaV!yi6a?Y zX86hOrh&eiZ7VAaXjE`aSO~xo(0T_D(m{S$I-hiPb^8HQOA1Zlx-sjir)tPA*@52? zb+6Iw)UL}c|K)8&taflgtmbiSr(VdAkYN%Cx56uMInj>mKO5~9|Ip^QT$RFUd8hMM zRgD|Ct)^9GZ&B@sN*js6G|U8Lbnt>~IVAZnPux16c4Jvq`T_-BAJ-Zeq0KA)>!oBQmLE(HrsG$V_o<8hgW@ldb1Ygf9i_{ee z2m1B9@UqHFEZUtCiXZLA;Z;_(H(5N>b31P)hMRL-dJ31%;Fi=aN|>smczVLlo!s4l zmLFStpSP)z0SX96%W>$$Z8QNJJA2t$WXe~aCjaL%@h<#r)4vwzTK)Eno4+`J9zBaH zhdc1P`q#uWDTKuJ+Z>hQZ*dvLQ0$?=5D%9%q>RuVPt8qXgF(f8eeX?yuMc&?$({LV z$(Hi+fA&^aSMNh3ED(DU)mmBI6xL@;hvYG|cKcF;+T7hyw0_>)H=A*4j>ce5=r);2 z@j$2hh6nTmA1TCv-&WVo~cv&1A z7x8aofm&Y_j@iuPXEAJ(CHvU+U~R79rHg<3u(SlIl_JU>K{QacpoacFDga&a9c;uG zN0`b&siR<+^^OwEz{~8Ce&K9(pba|&$#u3af1&2`KQXQ@4}Kxq-Am+slUIi2g=H~t;+m5#37 z^2iEyrx6DddmDnDOwVmi7Z3f}n2c`v&vDZmd<59T!$Z)jeH}G#QcxLBXTCxim6DS3 z9r#q9ANYHIh`oL^_I9|q!_kLH-XS&3wdo%{y&3yySY8(!<7cZa@R36z^e*2ArH=B4 z!f_RanbfK={|o!}T#w{xXlpmQ%kT+s^Q&4UK+q>ZR7+^A>0ud^(6ajY^kw9yQt}cd z_yVN(dEjKZhlRlT<=DQdm7bLJq~YXbWwW6h7*;0f?lEYG3sIYo)*%U%^M(KE)i?tK zHxuAaKsWS1@YgZb$vC$7``s}`j|RE($c@u%*;LU4XaM(Y$93+*N#ESAu26^f@;D*= zO}LyZqEneibLH3&xnt@&P9_$S@M}z1fb3BRd+s$FE8u<6T6osuN%K13dn;VG(eB(& zCp_n)q=H~>e>{t&3Chu3kb)u+`6VuveXdWB&)-b){aY?@xlAf35Yy8uJALrbjjhoN z2wgSVJ$h84AtSqh<%8*VEq-~c)oV(b5zbX^nHm|n=OSc$B$1F4xq(~gS_zH3W56!a zyo{E!3UXWI9RS@z0ffs!0{|zIxov$xv$^%lftvvm2FYj9Ea79fRt}PuAcIOWW}&sT z07L^-pY$jAy(uThjtA%le}IpOGFXh2{JTM|a?HBv9oOX(K&Jnin@kx$S!+RGBX8^EL@g{_ z@Lyo6cDTYXHFN+CC~g3u;Zz|A{ z!Bk7gn3Sb`J)CTTwWW}`#|AzX3haf;75oIYSs|f&gRX+E*-Yc0&W{&RgEKqcFat))U2FS`t1o28dzAS#6fQ9` z5kIAF@#10mMNz7X4jIL~ykQ_R@I}zzA*m%9qn+zB<)t`PMKa6_)#bIfwKdtyk@p$3 z#r(Z_OG{g5_B7}4Om_kcQyr=ZztDTtUp0yT@KRmS6c5W{t(X16QLh3t{Zr1oUemvD zJ3N)sP&L-muyC7?#0kZetW8lA6|B7PWTZ+xKJ- zTToyh95`%srMu87TyFK6Tiyzd)2^teT)8}o+1oQ9;xL*3Bvas~rmCqqQI71HcHz3~ zDpyJ06tOi*@go6-zBsllB?*tKxsZEj@_WeUR>b^Cj|ULIFn;XtFRx(XwVoynojLL! z-thoeHTQhynwa2<99o7p*o6HXN2wU<^yOuZjg5VN0WE51X^~D~C{@J1`8zIX_>|@$=(XdXc56j2|13mv_p?*A zQVpNZa0!JuvOQ8DV&)}sTscpu;pgY?+vxJFc`1d(`32l$;<@!FFo}rHXSB4qn_p_w z)`-3{$DQn&IQWU@LBe66DA%I|Cght zqbov=9Fk3urjWMANGWnG;_ip3yV_Rl30dImzyg(uRSeemWt{)~_< z6?Ikx6a(WDR;sYK53%GcSgi_QE@2|7N*##EA^WwZhyxA}34L%CfY{#LA_DeI3J#7` zfOr`vO+lRs5A0gdc@X(Zg4LAjn%GjRNhOAsRC4542 zDTo~yw?bKw)iivSQutew>~^!Z81M1rWiBfB4`iMZD4 zneIb)&|;%C0s z3dqAuErywYkt{HVnGWz(+>Ou7judK2N?V1Pw6r-m*xSDXt~7fdu*&OOXpUS%-^-d# z!}4v+=pJ8pNsrumUsXheRi??X=*+3%wv(!tA`Ut_P}buq`XNaJV*?_UXo}_$n~K^= zC0C$1H3guUr6iKmX@6mrHO63RCABG`coa{}=h0>*%%qEELJ2WdSJu!Xk<5MlZ_k@e za^YX!Zd*SO*69xlTtw|$7U_6<1GeC!mw>I&UZYFMDMb`7hq^iWhjl2nHO?nlYr7c; z#wd|NutJ$?7c;#~D+T*_pMa+-@9uVeQ2SUO_Ch7jZ@JGg6odtloYm82B*+}Hp z`2so&1X(m421*-FGZg3N=a)e2W9wexvgIPOZwDZ)2x%MnF6!kg8Cy2tu>fOn7Dj2Z zTSxq8Vld>o`LJVpV+QNmjs5_1N=ZMx&$_EstpfS2u!4AO(%YUtzJwO996a%ZXUG(l zVx_jsh-}c4l1}CYLLX4J+bRDMCBo+GR2gd1QF+YOXaKQ+-8P2$d{HH(l-Z@FrGIXo z2HSIU*VhrqU%(YZ-rjm&O^tjH(wl?}ofDQp#3v4qO##=!YXpI#ycqr48bf1o1Y3y* z_D8e*%g|X0TIHLZ>BSO}E;GF?9WST1c#cAv+q=qM?Nle5z$1H=X4;iV6!48IymFs!bQ*Xr>^7E5WD4*7)eYc6NXo~s4c z6FqoB{Vk>W&t@gz(k--d{_vYQ6ST!;zqF7)-Mg4Soy(&Cv-TuI-|1O&UKSI&&gN-M zFm<4|w6n@^9!qhy3p%8As8&WvHYFU+ebqAcWS%C|d&@|2wn9aB4$3U6_jfwy@|v&X zLn`=ja|R$B;m&+qLrnMk5a#x+P8AvjC24O5kf*nSvERM&4%Zw z^Rv}0&P~g$jkm9jD{tprN;DGwQsJC6lEvKLHbXe4#5xh8Kl!I%`SY7i39Z727^MZ- z@kSeMLlH4xa>xAI+L>4G)WaZf@cSw&Dk{QO_#P`iLRn4coj?R#|6yog^z1a4i36sn z*vu6<>~$?#E@<+#si@$zGLH@=v+{41vQLIZQ_wQikaBTl1A^wlV(ZN_I3ABJH75ng z^>pMx^aN#Zi@c)Rcr!);;IGaFsMy#}(ud2QnkVWB$EmcDF<+2m z7bkJ@ahiM zi@!vyW)5apME)d|7=^);z+~044P3le*5kt?u+y{C(cw7mXKfj9oGX}KB?;>3>v?l6 z@CXV8zk_ds6^dR|Wozq!DhQwWUv#FCpKaeVsJGNbbXwCFx~en%fV-Mut+mUJrcXsD zinTb(a346#V`h=fFxa89`S$nAn*Pl6rF-CSIZnt@3Uv?(Hir;(#W$)#*(zwF`aXkWLc@-`_f1E9`}K0~-*h^e$KlBto9PVj_n@_9VEw(d_iQ|`r(WL1Y>t~qWB4WW zeZm+QG|;^xBWr8ZvI^y?6||J-88VzkF0P75_iO@VgWn!?t@_`vg8kl&(=HmMw6IXp zxjounEG)1nZ(8Q*2(u)D#Hy2$Y^d>&R)FR4;o7}7z zTs$`!)?JwnV;r9DSTjq%SR_g>X~{ey00_*;u%fA}^TN_BZ&9aX%ao$jmWO(|pD-J{ z`pm?|WyG58`Sd27Ike+Lfrm704{#2)n#^UgNShrp~!2b^E6u>pj0yuR94warchc) znLbWqu>WoDe0izbKeVE#5qmhV7graaS-Bq40oVjg@k*SWj9MH3uFmXm z#+j6hDLN-cn%{t!x$8~=3Y{I|*6zhLQ1_J~YxFKZ5E$in&%vcDU+gn@zjgtC-JT*0i@Bta|>!XnkK+^^C5-NQP z0_M0urch%4X;$E^Rnwm@$G)`3ARx$7E$qT`*CBRNMvxTe*5gc;u|`9O!k1H>qeN%= zV_mq-5_*>B0VO7xVj=&avGW+onu| z5S}K+!tUZy0F3<*=HsIap$vzI`V7F?n08#AuvM{eUjzF70S9dQhwbZ~2#Sv3=S|%yi5saH^3iA@x-t}_VrW@f-4h?72isg``#EH`?ey9PWuji@Bw1;~`4;3I zFOK2v;FX?(-jG-FnZdmBsKhD=DcAlVBexlH_Him_SG=EBd1fY<*}_Kmjkg0FM{X@4-(*T?&!9 z`fZDp{2TRn^VekT%#unJxsg2U>C|IRgCr1lqMaJJ0r?PCX48&{eHhMv14QMdlqBoLO+x+$ DAqC!t literal 0 HcmV?d00001 diff --git a/admin/static/index.html b/admin/static/index.html index e2142455..c409ffa9 100644 --- a/admin/static/index.html +++ b/admin/static/index.html @@ -2,15 +2,40 @@ - Challenge Forensic FIC 2016 - Administration + Challenge Forensic - Administration + -
    -
    ","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ka.optgroup=ka.option;ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead;ka.th=ka.td;var Kf=Node.prototype.contains||function(a){return!!(this.compareDocumentPosition(a)& -16)},Pa=N.prototype={ready:function(a){function b(){d||(d=!0,a())}var d=!1;"complete"===X.readyState?setTimeout(b):(this.on("DOMContentLoaded",b),N(S).on("load",b))},toString:function(){var a=[];n(this,function(b){a.push(""+b)});return"["+a.join(", ")+"]"},eq:function(a){return 0<=a?B(this[a]):B(this[this.length+a])},length:0,push:mg,sort:[].sort,splice:[].splice},Cb={};n("multiple selected checked disabled readOnly required open".split(" "),function(a){Cb[F(a)]=a});var Rc={};n("input select option textarea button form details".split(" "), -function(a){Rc[a]=!0});var Zc={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"};n({data:Wb,removeData:vb,hasData:function(a){for(var b in gb[a.ng339])return!0;return!1}},function(a,b){N[b]=a});n({data:Wb,inheritedData:Bb,scope:function(a){return B.data(a,"$scope")||Bb(a.parentNode||a,["$isolateScope","$scope"])},isolateScope:function(a){return B.data(a,"$isolateScope")||B.data(a,"$isolateScopeNoTemplate")},controller:Oc,injector:function(a){return Bb(a, -"$injector")},removeAttr:function(a,b){a.removeAttribute(b)},hasClass:yb,css:function(a,b,d){b=fb(b);if(y(d))a.style[b]=d;else return a.style[b]},attr:function(a,b,d){var c=a.nodeType;if(c!==Na&&2!==c&&8!==c)if(c=F(b),Cb[c])if(y(d))d?(a[b]=!0,a.setAttribute(b,c)):(a[b]=!1,a.removeAttribute(c));else return a[b]||(a.attributes.getNamedItem(b)||x).specified?c:u;else if(y(d))a.setAttribute(b,d);else if(a.getAttribute)return a=a.getAttribute(b,2),null===a?u:a},prop:function(a,b,d){if(y(d))a[b]=d;else return a[b]}, -text:function(){function a(a,d){if(q(d)){var c=a.nodeType;return 1===c||c===Na?a.textContent:""}a.textContent=d}a.$dv="";return a}(),val:function(a,b){if(q(b)){if(a.multiple&&"select"===ta(a)){var d=[];n(a.options,function(a){a.selected&&d.push(a.value||a.text)});return 0===d.length?null:d}return a.value}a.value=b},html:function(a,b){if(q(b))return a.innerHTML;ub(a,!0);a.innerHTML=b},empty:Pc},function(a,b){N.prototype[b]=function(b,c){var e,f,g=this.length;if(a!==Pc&&q(2==a.length&&a!==yb&&a!==Oc? -b:c)){if(H(b)){for(e=0;e <= >= && || ! = |".split(" "),function(a){Lb[a]=!0});var sg={n:"\n",f:"\f",r:"\r", -t:"\t",v:"\v","'":"'",'"':'"'},fc=function(a){this.options=a};fc.prototype={constructor:fc,lex:function(a){this.text=a;this.index=0;for(this.tokens=[];this.index=a&&"string"===typeof a},isWhitespace:function(a){return" "===a||"\r"===a|| -"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,b,d){d=d||this.index;b=y(b)?"s "+b+"-"+this.index+" ["+this.text.substring(b,d)+"]":" "+d;throw ba("lexerr",a,b,this.text);},readNumber:function(){for(var a="",b=this.index;this.index","<=",">=");)a={type:s.BinaryExpression,operator:b.text,left:a,right:this.additive()};return a},additive:function(){for(var a=this.multiplicative(),b;b=this.expect("+","-");)a={type:s.BinaryExpression,operator:b.text,left:a,right:this.multiplicative()};return a},multiplicative:function(){for(var a=this.unary(),b;b=this.expect("*","/","%");)a={type:s.BinaryExpression,operator:b.text, -left:a,right:this.unary()};return a},unary:function(){var a;return(a=this.expect("+","-","!"))?{type:s.UnaryExpression,operator:a.text,prefix:!0,argument:this.unary()}:this.primary()},primary:function(){var a;this.expect("(")?(a=this.filterChain(),this.consume(")")):this.expect("[")?a=this.arrayDeclaration():this.expect("{")?a=this.object():this.constants.hasOwnProperty(this.peek().text)?a=bb(this.constants[this.consume().text]):this.peek().identifier?a=this.identifier():this.peek().constant?a=this.constant(): -this.throwError("not a primary expression",this.peek());for(var b;b=this.expect("(","[",".");)"("===b.text?(a={type:s.CallExpression,callee:a,arguments:this.parseArguments()},this.consume(")")):"["===b.text?(a={type:s.MemberExpression,object:a,property:this.expression(),computed:!0},this.consume("]")):"."===b.text?a={type:s.MemberExpression,object:a,property:this.identifier(),computed:!1}:this.throwError("IMPOSSIBLE");return a},filter:function(a){a=[a];for(var b={type:s.CallExpression,callee:this.identifier(), -arguments:a,filter:!0};this.expect(":");)a.push(this.expression());return b},parseArguments:function(){var a=[];if(")"!==this.peekToken().text){do a.push(this.expression());while(this.expect(","))}return a},identifier:function(){var a=this.consume();a.identifier||this.throwError("is not a valid identifier",a);return{type:s.Identifier,name:a.text}},constant:function(){return{type:s.Literal,value:this.consume().value}},arrayDeclaration:function(){var a=[];if("]"!==this.peekToken().text){do{if(this.peek("]"))break; -a.push(this.expression())}while(this.expect(","))}this.consume("]");return{type:s.ArrayExpression,elements:a}},object:function(){var a=[],b;if("}"!==this.peekToken().text){do{if(this.peek("}"))break;b={type:s.Property,kind:"init"};this.peek().constant?b.key=this.constant():this.peek().identifier?b.key=this.identifier():this.throwError("invalid key",this.peek());this.consume(":");b.value=this.expression();a.push(b)}while(this.expect(","))}this.consume("}");return{type:s.ObjectExpression,properties:a}}, -throwError:function(a,b){throw ba("syntax",b.text,a,b.index+1,this.text,this.text.substring(b.index));},consume:function(a){if(0===this.tokens.length)throw ba("ueoe",this.text);var b=this.expect(a);b||this.throwError("is unexpected, expecting ["+a+"]",this.peek());return b},peekToken:function(){if(0===this.tokens.length)throw ba("ueoe",this.text);return this.tokens[0]},peek:function(a,b,d,c){return this.peekAhead(0,a,b,d,c)},peekAhead:function(a,b,d,c,e){if(this.tokens.length>a){a=this.tokens[a]; -var f=a.text;if(f===b||f===d||f===c||f===e||!(b||d||c||e))return a}return!1},expect:function(a,b,d,c){return(a=this.peek(a,b,d,c))?(this.tokens.shift(),a):!1},constants:{"true":{type:s.Literal,value:!0},"false":{type:s.Literal,value:!1},"null":{type:s.Literal,value:null},undefined:{type:s.Literal,value:u},"this":{type:s.ThisExpression}}};rd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.state={nextId:0,filters:{},expensiveChecks:b,fn:{vars:[],body:[],own:{}},assign:{vars:[], -body:[],own:{}},inputs:[]};W(c,d.$filter);var e="",f;this.stage="assign";if(f=pd(c))this.state.computing="assign",e=this.nextId(),this.recurse(f,e),this.return_(e),e="fn.assign="+this.generateFunction("assign","s,v,l");f=nd(c.body);d.stage="inputs";n(f,function(a,b){var c="fn"+b;d.state[c]={vars:[],body:[],own:{}};d.state.computing=c;var e=d.nextId();d.recurse(a,e);d.return_(e);d.state.inputs.push(c);a.watchId=b});this.state.computing="fn";this.stage="main";this.recurse(c);e='"'+this.USE+" "+this.STRICT+ -'";\n'+this.filterPrefix()+"var fn="+this.generateFunction("fn","s,l,a,i")+e+this.watchFns()+"return fn;";e=(new Function("$filter","ensureSafeMemberName","ensureSafeObject","ensureSafeFunction","getStringValue","ensureSafeAssignContext","ifDefined","plus","text",e))(this.$filter,Va,xa,kd,jd,ld,Zf,md,a);this.state=this.stage=u;e.literal=qd(c);e.constant=c.constant;return e},USE:"use",STRICT:"strict",watchFns:function(){var a=[],b=this.state.inputs,d=this;n(b,function(b){a.push("var "+b+"="+d.generateFunction(b, -"s"))});b.length&&a.push("fn.inputs=["+b.join(",")+"];");return a.join("")},generateFunction:function(a,b){return"function("+b+"){"+this.varsPrefix(a)+this.body(a)+"};"},filterPrefix:function(){var a=[],b=this;n(this.state.filters,function(d,c){a.push(d+"=$filter("+b.escape(c)+")")});return a.length?"var "+a.join(",")+";":""},varsPrefix:function(a){return this.state[a].vars.length?"var "+this.state[a].vars.join(",")+";":""},body:function(a){return this.state[a].body.join("")},recurse:function(a,b, -d,c,e,f){var g,h,k=this,l,m;c=c||x;if(!f&&y(a.watchId))b=b||this.nextId(),this.if_("i",this.lazyAssign(b,this.computedMember("i",a.watchId)),this.lazyRecurse(a,b,d,c,e,!0));else switch(a.type){case s.Program:n(a.body,function(b,c){k.recurse(b.expression,u,u,function(a){h=a});c!==a.body.length-1?k.current().body.push(h,";"):k.return_(h)});break;case s.Literal:m=this.escape(a.value);this.assign(b,m);c(m);break;case s.UnaryExpression:this.recurse(a.argument,u,u,function(a){h=a});m=a.operator+"("+this.ifDefined(h, -0)+")";this.assign(b,m);c(m);break;case s.BinaryExpression:this.recurse(a.left,u,u,function(a){g=a});this.recurse(a.right,u,u,function(a){h=a});m="+"===a.operator?this.plus(g,h):"-"===a.operator?this.ifDefined(g,0)+a.operator+this.ifDefined(h,0):"("+g+")"+a.operator+"("+h+")";this.assign(b,m);c(m);break;case s.LogicalExpression:b=b||this.nextId();k.recurse(a.left,b);k.if_("&&"===a.operator?b:k.not(b),k.lazyRecurse(a.right,b));c(b);break;case s.ConditionalExpression:b=b||this.nextId();k.recurse(a.test, -b);k.if_(b,k.lazyRecurse(a.alternate,b),k.lazyRecurse(a.consequent,b));c(b);break;case s.Identifier:b=b||this.nextId();d&&(d.context="inputs"===k.stage?"s":this.assign(this.nextId(),this.getHasOwnProperty("l",a.name)+"?l:s"),d.computed=!1,d.name=a.name);Va(a.name);k.if_("inputs"===k.stage||k.not(k.getHasOwnProperty("l",a.name)),function(){k.if_("inputs"===k.stage||"s",function(){e&&1!==e&&k.if_(k.not(k.nonComputedMember("s",a.name)),k.lazyAssign(k.nonComputedMember("s",a.name),"{}"));k.assign(b,k.nonComputedMember("s", -a.name))})},b&&k.lazyAssign(b,k.nonComputedMember("l",a.name)));(k.state.expensiveChecks||Fb(a.name))&&k.addEnsureSafeObject(b);c(b);break;case s.MemberExpression:g=d&&(d.context=this.nextId())||this.nextId();b=b||this.nextId();k.recurse(a.object,g,u,function(){k.if_(k.notNull(g),function(){if(a.computed)h=k.nextId(),k.recurse(a.property,h),k.getStringValue(h),k.addEnsureSafeMemberName(h),e&&1!==e&&k.if_(k.not(k.computedMember(g,h)),k.lazyAssign(k.computedMember(g,h),"{}")),m=k.ensureSafeObject(k.computedMember(g, -h)),k.assign(b,m),d&&(d.computed=!0,d.name=h);else{Va(a.property.name);e&&1!==e&&k.if_(k.not(k.nonComputedMember(g,a.property.name)),k.lazyAssign(k.nonComputedMember(g,a.property.name),"{}"));m=k.nonComputedMember(g,a.property.name);if(k.state.expensiveChecks||Fb(a.property.name))m=k.ensureSafeObject(m);k.assign(b,m);d&&(d.computed=!1,d.name=a.property.name)}},function(){k.assign(b,"undefined")});c(b)},!!e);break;case s.CallExpression:b=b||this.nextId();a.filter?(h=k.filter(a.callee.name),l=[],n(a.arguments, -function(a){var b=k.nextId();k.recurse(a,b);l.push(b)}),m=h+"("+l.join(",")+")",k.assign(b,m),c(b)):(h=k.nextId(),g={},l=[],k.recurse(a.callee,h,g,function(){k.if_(k.notNull(h),function(){k.addEnsureSafeFunction(h);n(a.arguments,function(a){k.recurse(a,k.nextId(),u,function(a){l.push(k.ensureSafeObject(a))})});g.name?(k.state.expensiveChecks||k.addEnsureSafeObject(g.context),m=k.member(g.context,g.name,g.computed)+"("+l.join(",")+")"):m=h+"("+l.join(",")+")";m=k.ensureSafeObject(m);k.assign(b,m)}, -function(){k.assign(b,"undefined")});c(b)}));break;case s.AssignmentExpression:h=this.nextId();g={};if(!od(a.left))throw ba("lval");this.recurse(a.left,u,g,function(){k.if_(k.notNull(g.context),function(){k.recurse(a.right,h);k.addEnsureSafeObject(k.member(g.context,g.name,g.computed));k.addEnsureSafeAssignContext(g.context);m=k.member(g.context,g.name,g.computed)+a.operator+h;k.assign(b,m);c(b||m)})},1);break;case s.ArrayExpression:l=[];n(a.elements,function(a){k.recurse(a,k.nextId(),u,function(a){l.push(a)})}); -m="["+l.join(",")+"]";this.assign(b,m);c(m);break;case s.ObjectExpression:l=[];n(a.properties,function(a){k.recurse(a.value,k.nextId(),u,function(b){l.push(k.escape(a.key.type===s.Identifier?a.key.name:""+a.key.value)+":"+b)})});m="{"+l.join(",")+"}";this.assign(b,m);c(m);break;case s.ThisExpression:this.assign(b,"s");c("s");break;case s.NGValueParameter:this.assign(b,"v"),c("v")}},getHasOwnProperty:function(a,b){var d=a+"."+b,c=this.current().own;c.hasOwnProperty(d)||(c[d]=this.nextId(!1,a+"&&("+ -this.escape(b)+" in "+a+")"));return c[d]},assign:function(a,b){if(a)return this.current().body.push(a,"=",b,";"),a},filter:function(a){this.state.filters.hasOwnProperty(a)||(this.state.filters[a]=this.nextId(!0));return this.state.filters[a]},ifDefined:function(a,b){return"ifDefined("+a+","+this.escape(b)+")"},plus:function(a,b){return"plus("+a+","+b+")"},return_:function(a){this.current().body.push("return ",a,";")},if_:function(a,b,d){if(!0===a)b();else{var c=this.current().body;c.push("if(",a, -"){");b();c.push("}");d&&(c.push("else{"),d(),c.push("}"))}},not:function(a){return"!("+a+")"},notNull:function(a){return a+"!=null"},nonComputedMember:function(a,b){return a+"."+b},computedMember:function(a,b){return a+"["+b+"]"},member:function(a,b,d){return d?this.computedMember(a,b):this.nonComputedMember(a,b)},addEnsureSafeObject:function(a){this.current().body.push(this.ensureSafeObject(a),";")},addEnsureSafeMemberName:function(a){this.current().body.push(this.ensureSafeMemberName(a),";")}, -addEnsureSafeFunction:function(a){this.current().body.push(this.ensureSafeFunction(a),";")},addEnsureSafeAssignContext:function(a){this.current().body.push(this.ensureSafeAssignContext(a),";")},ensureSafeObject:function(a){return"ensureSafeObject("+a+",text)"},ensureSafeMemberName:function(a){return"ensureSafeMemberName("+a+",text)"},ensureSafeFunction:function(a){return"ensureSafeFunction("+a+",text)"},getStringValue:function(a){this.assign(a,"getStringValue("+a+",text)")},ensureSafeAssignContext:function(a){return"ensureSafeAssignContext("+ -a+",text)"},lazyRecurse:function(a,b,d,c,e,f){var g=this;return function(){g.recurse(a,b,d,c,e,f)}},lazyAssign:function(a,b){var d=this;return function(){d.assign(a,b)}},stringEscapeRegex:/[^ a-zA-Z0-9]/g,stringEscapeFn:function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)},escape:function(a){if(E(a))return"'"+a.replace(this.stringEscapeRegex,this.stringEscapeFn)+"'";if(Q(a))return a.toString();if(!0===a)return"true";if(!1===a)return"false";if(null===a)return"null";if("undefined"=== -typeof a)return"undefined";throw ba("esc");},nextId:function(a,b){var d="v"+this.state.nextId++;a||this.current().vars.push(d+(b?"="+b:""));return d},current:function(){return this.state[this.state.computing]}};sd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.expression=a;this.expensiveChecks=b;W(c,d.$filter);var e,f;if(e=pd(c))f=this.recurse(e);e=nd(c.body);var g;e&&(g=[],n(e,function(a,b){var c=d.recurse(a);a.input=c;g.push(c);a.watchId=b}));var h=[];n(c.body,function(a){h.push(d.recurse(a.expression))}); -e=0===c.body.length?function(){}:1===c.body.length?h[0]:function(a,b){var c;n(h,function(d){c=d(a,b)});return c};f&&(e.assign=function(a,b,c){return f(a,c,b)});g&&(e.inputs=g);e.literal=qd(c);e.constant=c.constant;return e},recurse:function(a,b,d){var c,e,f=this,g;if(a.input)return this.inputs(a.input,a.watchId);switch(a.type){case s.Literal:return this.value(a.value,b);case s.UnaryExpression:return e=this.recurse(a.argument),this["unary"+a.operator](e,b);case s.BinaryExpression:return c=this.recurse(a.left), -e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case s.LogicalExpression:return c=this.recurse(a.left),e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case s.ConditionalExpression:return this["ternary?:"](this.recurse(a.test),this.recurse(a.alternate),this.recurse(a.consequent),b);case s.Identifier:return Va(a.name,f.expression),f.identifier(a.name,f.expensiveChecks||Fb(a.name),b,d,f.expression);case s.MemberExpression:return c=this.recurse(a.object,!1,!!d),a.computed||(Va(a.property.name, -f.expression),e=a.property.name),a.computed&&(e=this.recurse(a.property)),a.computed?this.computedMember(c,e,b,d,f.expression):this.nonComputedMember(c,e,f.expensiveChecks,b,d,f.expression);case s.CallExpression:return g=[],n(a.arguments,function(a){g.push(f.recurse(a))}),a.filter&&(e=this.$filter(a.callee.name)),a.filter||(e=this.recurse(a.callee,!0)),a.filter?function(a,c,d,f){for(var r=[],n=0;n":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)>b(c,e,f,g);return d?{value:c}:c}},"binary<=":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)<=b(c,e,f,g);return d?{value:c}:c}},"binary>=":function(a,b,d){return function(c, -e,f,g){c=a(c,e,f,g)>=b(c,e,f,g);return d?{value:c}:c}},"binary&&":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)&&b(c,e,f,g);return d?{value:c}:c}},"binary||":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)||b(c,e,f,g);return d?{value:c}:c}},"ternary?:":function(a,b,d,c){return function(e,f,g,h){e=a(e,f,g,h)?b(e,f,g,h):d(e,f,g,h);return c?{value:e}:e}},value:function(a,b){return function(){return b?{context:u,name:u,value:a}:a}},identifier:function(a,b,d,c,e){return function(f,g,h,k){f= -g&&a in g?g:f;c&&1!==c&&f&&!f[a]&&(f[a]={});g=f?f[a]:u;b&&xa(g,e);return d?{context:f,name:a,value:g}:g}},computedMember:function(a,b,d,c,e){return function(f,g,h,k){var l=a(f,g,h,k),m,n;null!=l&&(m=b(f,g,h,k),m=jd(m),Va(m,e),c&&1!==c&&l&&!l[m]&&(l[m]={}),n=l[m],xa(n,e));return d?{context:l,name:m,value:n}:n}},nonComputedMember:function(a,b,d,c,e,f){return function(g,h,k,l){g=a(g,h,k,l);e&&1!==e&&g&&!g[b]&&(g[b]={});h=null!=g?g[b]:u;(d||Fb(b))&&xa(h,f);return c?{context:g,name:b,value:h}:h}},inputs:function(a, -b){return function(d,c,e,f){return f?f[b]:a(d,c,e)}}};var gc=function(a,b,d){this.lexer=a;this.$filter=b;this.options=d;this.ast=new s(this.lexer);this.astCompiler=d.csp?new sd(this.ast,b):new rd(this.ast,b)};gc.prototype={constructor:gc,parse:function(a){return this.astCompiler.compile(a,this.options.expensiveChecks)}};$();$();var $f=Object.prototype.valueOf,ya=G("$sce"),la={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},ha=G("$compile"),Y=X.createElement("a"),wd=wa(S.location.href); -xd.$inject=["$document"];Jc.$inject=["$provide"];yd.$inject=["$locale"];Ad.$inject=["$locale"];var ic=".",jg={yyyy:ca("FullYear",4),yy:ca("FullYear",2,0,!0),y:ca("FullYear",1),MMMM:Hb("Month"),MMM:Hb("Month",!0),MM:ca("Month",2,1),M:ca("Month",1,1),dd:ca("Date",2),d:ca("Date",1),HH:ca("Hours",2),H:ca("Hours",1),hh:ca("Hours",2,-12),h:ca("Hours",1,-12),mm:ca("Minutes",2),m:ca("Minutes",1),ss:ca("Seconds",2),s:ca("Seconds",1),sss:ca("Milliseconds",3),EEEE:Hb("Day"),EEE:Hb("Day",!0),a:function(a,b){return 12> -a.getHours()?b.AMPMS[0]:b.AMPMS[1]},Z:function(a,b,d){a=-1*d;return a=(0<=a?"+":"")+(Gb(Math[0=a.getFullYear()?b.ERANAMES[0]:b.ERANAMES[1]}},ig=/((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,hg=/^\-?\d+$/;zd.$inject=["$locale"];var eg=na(F),fg=na(sb);Bd.$inject=["$parse"];var he=na({restrict:"E",compile:function(a,b){if(!b.href&&!b.xlinkHref)return function(a, -b){if("a"===b[0].nodeName.toLowerCase()){var e="[object SVGAnimatedString]"===sa.call(b.prop("href"))?"xlink:href":"href";b.on("click",function(a){b.attr(e)||a.preventDefault()})}}}}),tb={};n(Cb,function(a,b){function d(a,d,e){a.$watch(e[c],function(a){e.$set(b,!!a)})}if("multiple"!=a){var c=va("ng-"+b),e=d;"checked"===a&&(e=function(a,b,e){e.ngModel!==e[c]&&d(a,b,e)});tb[c]=function(){return{restrict:"A",priority:100,link:e}}}});n(Zc,function(a,b){tb[b]=function(){return{priority:100,link:function(a, -c,e){if("ngPattern"===b&&"/"==e.ngPattern.charAt(0)&&(c=e.ngPattern.match(lg))){e.$set("ngPattern",new RegExp(c[1],c[2]));return}a.$watch(e[b],function(a){e.$set(b,a)})}}}});n(["src","srcset","href"],function(a){var b=va("ng-"+a);tb[b]=function(){return{priority:99,link:function(d,c,e){var f=a,g=a;"href"===a&&"[object SVGAnimatedString]"===sa.call(c.prop("href"))&&(g="xlinkHref",e.$attr[g]="xlink:href",f=null);e.$observe(b,function(b){b?(e.$set(g,b),Ha&&f&&c.prop(f,e[g])):"href"===a&&e.$set(g,null)})}}}}); -var Ib={$addControl:x,$$renameControl:function(a,b){a.$name=b},$removeControl:x,$setValidity:x,$setDirty:x,$setPristine:x,$setSubmitted:x};Fd.$inject=["$element","$attrs","$scope","$animate","$interpolate"];var Nd=function(a){return["$timeout","$parse",function(b,d){function c(a){return""===a?d('this[""]').assign:d(a).assign||x}return{name:"form",restrict:a?"EAC":"E",require:["form","^^?form"],controller:Fd,compile:function(d,f){d.addClass(Wa).addClass(mb);var g=f.name?"name":a&&f.ngForm?"ngForm": -!1;return{pre:function(a,d,e,f){var n=f[0];if(!("action"in e)){var q=function(b){a.$apply(function(){n.$commitViewValue();n.$setSubmitted()});b.preventDefault()};d[0].addEventListener("submit",q,!1);d.on("$destroy",function(){b(function(){d[0].removeEventListener("submit",q,!1)},0,!1)})}(f[1]||n.$$parentForm).$addControl(n);var s=g?c(n.$name):x;g&&(s(a,n),e.$observe(g,function(b){n.$name!==b&&(s(a,u),n.$$parentForm.$$renameControl(n,b),s=c(n.$name),s(a,n))}));d.on("$destroy",function(){n.$$parentForm.$removeControl(n); -s(a,u);M(n,Ib)})}}}}}]},ie=Nd(),ve=Nd(!0),kg=/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/,tg=/^[A-Za-z][A-Za-z\d.+-]*:\/*(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?(?:\/[\w#!:.?+=&%@\-/]*)?$/,ug=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,vg=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/,Od=/^(\d{4})-(\d{2})-(\d{2})$/,Pd=/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,mc=/^(\d{4})-W(\d\d)$/,Qd=/^(\d{4})-(\d\d)$/, -Rd=/^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,Sd={text:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c)},date:kb("date",Od,Kb(Od,["yyyy","MM","dd"]),"yyyy-MM-dd"),"datetime-local":kb("datetimelocal",Pd,Kb(Pd,"yyyy MM dd HH mm ss sss".split(" ")),"yyyy-MM-ddTHH:mm:ss.sss"),time:kb("time",Rd,Kb(Rd,["HH","mm","ss","sss"]),"HH:mm:ss.sss"),week:kb("week",mc,function(a,b){if(da(a))return a;if(E(a)){mc.lastIndex=0;var d=mc.exec(a);if(d){var c=+d[1],e=+d[2],f=d=0,g=0,h=0,k=Dd(c),e=7*(e-1);b&&(d=b.getHours(),f= -b.getMinutes(),g=b.getSeconds(),h=b.getMilliseconds());return new Date(c,0,k.getDate()+e,d,f,g,h)}}return NaN},"yyyy-Www"),month:kb("month",Qd,Kb(Qd,["yyyy","MM"]),"yyyy-MM"),number:function(a,b,d,c,e,f){Hd(a,b,d,c);jb(a,b,d,c,e,f);c.$$parserName="number";c.$parsers.push(function(a){return c.$isEmpty(a)?null:vg.test(a)?parseFloat(a):u});c.$formatters.push(function(a){if(!c.$isEmpty(a)){if(!Q(a))throw lb("numfmt",a);a=a.toString()}return a});if(y(d.min)||d.ngMin){var g;c.$validators.min=function(a){return c.$isEmpty(a)|| -q(g)||a>=g};d.$observe("min",function(a){y(a)&&!Q(a)&&(a=parseFloat(a,10));g=Q(a)&&!isNaN(a)?a:u;c.$validate()})}if(y(d.max)||d.ngMax){var h;c.$validators.max=function(a){return c.$isEmpty(a)||q(h)||a<=h};d.$observe("max",function(a){y(a)&&!Q(a)&&(a=parseFloat(a,10));h=Q(a)&&!isNaN(a)?a:u;c.$validate()})}},url:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c);c.$$parserName="url";c.$validators.url=function(a,b){var d=a||b;return c.$isEmpty(d)||tg.test(d)}},email:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c); -c.$$parserName="email";c.$validators.email=function(a,b){var d=a||b;return c.$isEmpty(d)||ug.test(d)}},radio:function(a,b,d,c){q(d.name)&&b.attr("name",++nb);b.on("click",function(a){b[0].checked&&c.$setViewValue(d.value,a&&a.type)});c.$render=function(){b[0].checked=d.value==c.$viewValue};d.$observe("value",c.$render)},checkbox:function(a,b,d,c,e,f,g,h){var k=Id(h,a,"ngTrueValue",d.ngTrueValue,!0),l=Id(h,a,"ngFalseValue",d.ngFalseValue,!1);b.on("click",function(a){c.$setViewValue(b[0].checked,a&& -a.type)});c.$render=function(){b[0].checked=c.$viewValue};c.$isEmpty=function(a){return!1===a};c.$formatters.push(function(a){return ma(a,k)});c.$parsers.push(function(a){return a?k:l})},hidden:x,button:x,submit:x,reset:x,file:x},Dc=["$browser","$sniffer","$filter","$parse",function(a,b,d,c){return{restrict:"E",require:["?ngModel"],link:{pre:function(e,f,g,h){h[0]&&(Sd[F(g.type)]||Sd.text)(e,f,g,h[0],b,a,d,c)}}}}],wg=/^(true|false|\d+)$/,Ne=function(){return{restrict:"A",priority:100,compile:function(a, -b){return wg.test(b.ngValue)?function(a,b,e){e.$set("value",a.$eval(e.ngValue))}:function(a,b,e){a.$watch(e.ngValue,function(a){e.$set("value",a)})}}}},ne=["$compile",function(a){return{restrict:"AC",compile:function(b){a.$$addBindingClass(b);return function(b,c,e){a.$$addBindingInfo(c,e.ngBind);c=c[0];b.$watch(e.ngBind,function(a){c.textContent=q(a)?"":a})}}}}],pe=["$interpolate","$compile",function(a,b){return{compile:function(d){b.$$addBindingClass(d);return function(c,d,f){c=a(d.attr(f.$attr.ngBindTemplate)); -b.$$addBindingInfo(d,c.expressions);d=d[0];f.$observe("ngBindTemplate",function(a){d.textContent=q(a)?"":a})}}}}],oe=["$sce","$parse","$compile",function(a,b,d){return{restrict:"A",compile:function(c,e){var f=b(e.ngBindHtml),g=b(e.ngBindHtml,function(a){return(a||"").toString()});d.$$addBindingClass(c);return function(b,c,e){d.$$addBindingInfo(c,e.ngBindHtml);b.$watch(g,function(){c.html(a.getTrustedHtml(f(b))||"")})}}}}],Me=na({restrict:"A",require:"ngModel",link:function(a,b,d,c){c.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}), -qe=lc("",!0),se=lc("Odd",0),re=lc("Even",1),te=La({compile:function(a,b){b.$set("ngCloak",u);a.removeClass("ng-cloak")}}),ue=[function(){return{restrict:"A",scope:!0,controller:"@",priority:500}}],Ic={},xg={blur:!0,focus:!0};n("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var b=va("ng-"+a);Ic[b]=["$parse","$rootScope",function(d,c){return{restrict:"A",compile:function(e,f){var g= -d(f[b],null,!0);return function(b,d){d.on(a,function(d){var e=function(){g(b,{$event:d})};xg[a]&&c.$$phase?b.$evalAsync(e):b.$apply(e)})}}}}]});var xe=["$animate",function(a){return{multiElement:!0,transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(b,d,c,e,f){var g,h,k;b.$watch(c.ngIf,function(b){b?h||f(function(b,e){h=e;b[b.length++]=X.createComment(" end ngIf: "+c.ngIf+" ");g={clone:b};a.enter(b,d.parent(),d)}):(k&&(k.remove(),k=null),h&&(h.$destroy(),h=null),g&&(k= -rb(g.clone),a.leave(k).then(function(){k=null}),g=null))})}}}],ye=["$templateRequest","$anchorScroll","$animate",function(a,b,d){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:fa.noop,compile:function(c,e){var f=e.ngInclude||e.src,g=e.onload||"",h=e.autoscroll;return function(c,e,m,n,q){var s=0,v,u,p,C=function(){u&&(u.remove(),u=null);v&&(v.$destroy(),v=null);p&&(d.leave(p).then(function(){u=null}),u=p,p=null)};c.$watch(f,function(f){var m=function(){!y(h)||h&&!c.$eval(h)|| -b()},u=++s;f?(a(f,!0).then(function(a){if(u===s){var b=c.$new();n.template=a;a=q(b,function(a){C();d.enter(a,null,e).then(m)});v=b;p=a;v.$emit("$includeContentLoaded",f);c.$eval(g)}},function(){u===s&&(C(),c.$emit("$includeContentError",f))}),c.$emit("$includeContentRequested",f)):(C(),n.template=null)})}}}}],Pe=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(b,d,c,e){/SVG/.test(d[0].toString())?(d.empty(),a(Lc(e.template,X).childNodes)(b,function(a){d.append(a)}, -{futureParentElement:d})):(d.html(e.template),a(d.contents())(b))}}}],ze=La({priority:450,compile:function(){return{pre:function(a,b,d){a.$eval(d.ngInit)}}}}),Le=function(){return{restrict:"A",priority:100,require:"ngModel",link:function(a,b,d,c){var e=b.attr(d.$attr.ngList)||", ",f="false"!==d.ngTrim,g=f?U(e):e;c.$parsers.push(function(a){if(!q(a)){var b=[];a&&n(a.split(g),function(a){a&&b.push(f?U(a):a)});return b}});c.$formatters.push(function(a){return I(a)?a.join(e):u});c.$isEmpty=function(a){return!a|| -!a.length}}}},mb="ng-valid",Jd="ng-invalid",Wa="ng-pristine",Jb="ng-dirty",Ld="ng-pending",lb=G("ngModel"),yg=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q","$interpolate",function(a,b,d,c,e,f,g,h,k,l){this.$modelValue=this.$viewValue=Number.NaN;this.$$rawModelValue=u;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;this.$touched=!1;this.$pristine=!0;this.$dirty=!1; -this.$valid=!0;this.$invalid=!1;this.$error={};this.$$success={};this.$pending=u;this.$name=l(d.name||"",!1)(a);this.$$parentForm=Ib;var m=e(d.ngModel),r=m.assign,t=m,s=r,v=null,B,p=this;this.$$setOptions=function(a){if((p.$options=a)&&a.getterSetter){var b=e(d.ngModel+"()"),f=e(d.ngModel+"($$$p)");t=function(a){var c=m(a);z(c)&&(c=b(a));return c};s=function(a,b){z(m(a))?f(a,{$$$p:p.$modelValue}):r(a,p.$modelValue)}}else if(!m.assign)throw lb("nonassign",d.ngModel,ua(c));};this.$render=x;this.$isEmpty= -function(a){return q(a)||""===a||null===a||a!==a};var C=0;Gd({ctrl:this,$element:c,set:function(a,b){a[b]=!0},unset:function(a,b){delete a[b]},$animate:f});this.$setPristine=function(){p.$dirty=!1;p.$pristine=!0;f.removeClass(c,Jb);f.addClass(c,Wa)};this.$setDirty=function(){p.$dirty=!0;p.$pristine=!1;f.removeClass(c,Wa);f.addClass(c,Jb);p.$$parentForm.$setDirty()};this.$setUntouched=function(){p.$touched=!1;p.$untouched=!0;f.setClass(c,"ng-untouched","ng-touched")};this.$setTouched=function(){p.$touched= -!0;p.$untouched=!1;f.setClass(c,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){g.cancel(v);p.$viewValue=p.$$lastCommittedViewValue;p.$render()};this.$validate=function(){if(!Q(p.$modelValue)||!isNaN(p.$modelValue)){var a=p.$$rawModelValue,b=p.$valid,c=p.$modelValue,d=p.$options&&p.$options.allowInvalid;p.$$runValidators(a,p.$$lastCommittedViewValue,function(e){d||b===e||(p.$modelValue=e?a:u,p.$modelValue!==c&&p.$$writeModelToScope())})}};this.$$runValidators=function(a,b,c){function d(){var c= -!0;n(p.$validators,function(d,e){var g=d(a,b);c=c&&g;f(e,g)});return c?!0:(n(p.$asyncValidators,function(a,b){f(b,null)}),!1)}function e(){var c=[],d=!0;n(p.$asyncValidators,function(e,g){var h=e(a,b);if(!h||!z(h.then))throw lb("$asyncValidators",h);f(g,u);c.push(h.then(function(){f(g,!0)},function(a){d=!1;f(g,!1)}))});c.length?k.all(c).then(function(){g(d)},x):g(!0)}function f(a,b){h===C&&p.$setValidity(a,b)}function g(a){h===C&&c(a)}C++;var h=C;(function(){var a=p.$$parserName||"parse";if(q(B))f(a, -null);else return B||(n(p.$validators,function(a,b){f(b,null)}),n(p.$asyncValidators,function(a,b){f(b,null)})),f(a,B),B;return!0})()?d()?e():g(!1):g(!1)};this.$commitViewValue=function(){var a=p.$viewValue;g.cancel(v);if(p.$$lastCommittedViewValue!==a||""===a&&p.$$hasNativeValidators)p.$$lastCommittedViewValue=a,p.$pristine&&this.$setDirty(),this.$$parseAndValidate()};this.$$parseAndValidate=function(){var b=p.$$lastCommittedViewValue;if(B=q(b)?u:!0)for(var c=0;ce||c.$isEmpty(b)||b.length<=e}}}}},Gc=function(){return{restrict:"A",require:"?ngModel",link:function(a,b,d,c){if(c){var e=0;d.$observe("minlength",function(a){e=ea(a)||0;c.$validate()});c.$validators.minlength=function(a,b){return c.$isEmpty(b)||b.length>=e}}}}};S.angular.bootstrap? -console.log("WARNING: Tried to load angular more than once."):(ce(),ee(fa),fa.module("ngLocale",[],["$provide",function(a){function b(a){a+="";var b=a.indexOf(".");return-1==b?0:a.length-b-1}a.value("$locale",{DATETIME_FORMATS:{AMPMS:["AM","PM"],DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),ERANAMES:["Before Christ","Anno Domini"],ERAS:["BC","AD"],FIRSTDAYOFWEEK:6,MONTH:"January February March April May June July August September October November December".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "), -SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),WEEKENDRANGE:[5,6],fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",medium:"MMM d, y h:mm:ss a",mediumDate:"MMM d, y",mediumTime:"h:mm:ss a","short":"M/d/yy h:mm a",shortDate:"M/d/yy",shortTime:"h:mm a"},NUMBER_FORMATS:{CURRENCY_SYM:"$",DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{gSize:3,lgSize:3,maxFrac:3,minFrac:0,minInt:1,negPre:"-",negSuf:"",posPre:"",posSuf:""},{gSize:3,lgSize:3,maxFrac:2,minFrac:2,minInt:1,negPre:"-\u00a4", -negSuf:"",posPre:"\u00a4",posSuf:""}]},id:"en-us",pluralCat:function(a,c){var e=a|0,f=c;u===f&&(f=Math.min(b(a),3));Math.pow(10,f);return 1==e&&0==f?"one":"other"}})}]),B(X).ready(function(){Zd(X,yc)}))})(window,document);!window.angular.$$csp().noInlineStyle&&window.angular.element(document.head).prepend(''); -//# sourceMappingURL=angular.min.js.map diff --git a/admin/static/js/angular.min.js b/admin/static/js/angular.min.js new file mode 120000 index 00000000..86b88964 --- /dev/null +++ b/admin/static/js/angular.min.js @@ -0,0 +1 @@ +../../../frontend/static/js/angular.min.js \ No newline at end of file diff --git a/admin/static/js/bootstrap.min.js b/admin/static/js/bootstrap.min.js deleted file mode 100644 index e79c0651..00000000 --- a/admin/static/js/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 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&&jdocument.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
    ',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-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.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:''}),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[a]&&(void 0===e[a+1]||b .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/admin/static/js/bootstrap.min.js b/admin/static/js/bootstrap.min.js new file mode 120000 index 00000000..d074c9db --- /dev/null +++ b/admin/static/js/bootstrap.min.js @@ -0,0 +1 @@ +../../../frontend/static/js/bootstrap.min.js \ No newline at end of file diff --git a/admin/static/js/jquery.min.js b/admin/static/js/jquery.min.js deleted file mode 100644 index 6c60672f..00000000 --- a/admin/static/js/jquery.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! jQuery v1.12.0 | (c) jQuery Foundation | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; -return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
    a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n(" +
    + +
    From 8c2e8a19d1e43e5ff93eaa427d0803d37dd6d45a Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 5 Jan 2017 02:18:31 +0100 Subject: [PATCH 0379/2518] front: use ng-pluralize --- frontend/static/index.html | 6 +++--- frontend/static/views/theme.html | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/static/index.html b/frontend/static/index.html index 01de3f90..84c638b4 100644 --- a/frontend/static/index.html +++ b/frontend/static/index.html @@ -83,8 +83,8 @@
    - {{ teams[my.team_id].rank }}e sur {{ teams_count }} – - {{ my.score }} points + {{ teams[my.team_id].rank }} sur {{ teams_count }} – +
    @@ -97,7 +97,7 @@
    diff --git a/frontend/static/views/theme.html b/frontend/static/views/theme.html index ebaf8c8c..792cf571 100644 --- a/frontend/static/views/theme.html +++ b/frontend/static/views/theme.html @@ -8,8 +8,8 @@

      -
    • Gain : {{ themes[current_theme].exercices[current_exercice].gain }} points +50% happy hour +50% first blood
    • -
    • Résolu par : {{ themes[current_theme].exercices[current_exercice].solved }} équipes
    • +
    • Gain : +50% happy hour +50% first blood
    • +
    • Résolu par : .
    @@ -37,7 +37,7 @@

    {{ hint.title }}

    -

    Cet indice vous coûtera {{ hint.cost }}% des points de l'exercice

    +

    Débloquer cet indice vous coûtera .

    @@ -47,7 +47,7 @@
    Soumettre une solution
      -
    • {{ my.exercices[current_exercice].solved_number }} tentative(s) effectuée(s). Dernière solution envoyée à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}.
    • +
    • . Dernière solution envoyée à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}.
    • Votre solution a bien été envoyée !{{ sberr }} {{ message }}
    @@ -69,7 +69,7 @@
    Challenge réussi !
    - Vous êtes la {{ my.exercices[current_exercice].solved_number }}e équipe à avoir résolu ce challenge à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}. Vous avez marqué {{ themes[current_theme].exercices[current_exercice].gain }} points ! + Vous êtes la {{ my.exercices[current_exercice].solved_number }} équipe à avoir résolu ce challenge à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}. Vous avez marqué !
    From b772a227057508723fcc50983f0b6ca14d1592c5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 5 Jan 2017 02:21:32 +0100 Subject: [PATCH 0380/2518] Hints can something else than text --- admin/api/exercice.go | 30 +++++++++++++++++++++++---- admin/api/file.go | 12 +++-------- admin/fill_exercices.sh | 35 ++++++++++++++++++++++++-------- frontend/static/views/theme.html | 4 +++- libfic/file.go | 3 +-- libfic/hint.go | 10 +++++++++ 6 files changed, 69 insertions(+), 25 deletions(-) diff --git a/admin/api/exercice.go b/admin/api/exercice.go index e00772e7..309a0d71 100644 --- a/admin/api/exercice.go +++ b/admin/api/exercice.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "errors" + "strings" "srs.epita.fr/fic-server/libfic" @@ -119,17 +120,29 @@ func createExerciceKey(exercice fic.Exercice, body []byte) (interface{}, error) return exercice.AddRawKey(uk.Type, uk.Key) } +type uploadedHint struct { + Title string + Content string + Cost int64 + Path string +} + func createExerciceHint(exercice fic.Exercice, body []byte) (interface{}, error) { - var uh fic.EHint + var uh uploadedHint if err := json.Unmarshal(body, &uh); err != nil { return nil, err } - if len(uh.Content) == 0 { + if len(uh.Content) != 0 { + return exercice.AddHint(uh.Title, uh.Content, uh.Cost) + } else if len(uh.Path) != 0 { + return importFile(uploadedFile{Path: uh.Path}, + func(filePath string, origin string, digest []byte) (interface{}, error) { + return exercice.AddHint(uh.Title, "$FILES" + strings.TrimPrefix(filePath, fic.FilesDir), uh.Cost) + }) + } else { return nil, errors.New("Hint's content not filled") } - - return exercice.AddHint(uh.Title, uh.Content, uh.Cost) } func showExerciceHint(hint fic.EHint, body []byte) (interface{}, error) { @@ -189,6 +202,15 @@ func deleteExerciceKey(key fic.Key, _ fic.Exercice, _ []byte) (interface{}, erro } +func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) { + var uf uploadedFile + if err := json.Unmarshal(body, &uf); err != nil { + return nil, err + } + + return importFile(uf, exercice.ImportFile) +} + func showExerciceFile(file fic.EFile, body []byte) (interface{}, error) { return file, nil } diff --git a/admin/api/file.go b/admin/api/file.go index e8667107..66d8dc46 100644 --- a/admin/api/file.go +++ b/admin/api/file.go @@ -5,7 +5,6 @@ import ( "crypto/sha512" "encoding/base32" "encoding/hex" - "encoding/json" "errors" "fmt" "log" @@ -29,12 +28,7 @@ type uploadedFile struct { Parts []string } -func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) { - var uf uploadedFile - if err := json.Unmarshal(body, &uf); err != nil { - return nil, err - } - +func importFile(uf uploadedFile, next func(string, string, []byte) (interface{}, error)) (interface{}, error) { var hash [sha512.Size]byte var logStr string var fromURI string @@ -80,7 +74,7 @@ func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) pathname := path.Join(fic.FilesDir, strings.ToLower(base32.StdEncoding.EncodeToString(hash[:])), path.Base(fromURI)) // Remove the file if it exists - if _, err := os.Stat(pathname); os.IsExist(err) && !RapidImport { + if _, err := os.Stat(pathname); !os.IsNotExist(err) && !RapidImport { if err := os.Remove(pathname); err != nil { return nil, err } @@ -98,7 +92,7 @@ func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) if digest, err := hex.DecodeString(uf.Digest); err != nil { return nil, err } else { - return exercice.ImportFile(pathname, fromURI, digest) + return next(pathname, fromURI, digest) } } diff --git a/admin/fill_exercices.sh b/admin/fill_exercices.sh index 149fad64..b57756b6 100755 --- a/admin/fill_exercices.sh +++ b/admin/fill_exercices.sh @@ -59,8 +59,12 @@ new_hint() { TITLE=`echo "$3" | sed 's/"/\\\\"/g'` CONTENT=`echo "$4" | sed 's/"/\\\\"/g' | sed ':a;N;$!ba;s/\n/
    /g'` COST="$5" + URI="$6" - curl -f -s -d "{\"title\": \"$TITLE\", \"content\": \"$CONTENT\", \"cost\": $COST}" "${BASEURL}/api/themes/$THEME/exercices/$EXERCICE/hints" | + [ -n "${CONTENT}" ] && CONTENT=", \"content\": \"${CONTENT}\"" + [ -n "${URI}" ] && URI=", \"path\": \"${BASEFILE}${URI}\"" + + curl -f -s -d "{\"title\": \"$TITLE\"$CONTENT$URI, \"cost\": $COST}" "${BASEURL}/api/themes/$THEME/exercices/$EXERCICE/hints" | grep -Eo '"id":[0-9]+,' | grep -Eo "[0-9]+" } @@ -191,15 +195,28 @@ do # Hints - EXO_HINT=$(get_file "${THM_BASEURI}${EXO_BASEURI}/hint.txt") - if [ -n "$EXO_HINT" ]; then - HINT_ID=`new_hint "${THEME_ID}" "${EXO_ID}" "Astuce #1" "${EXO_HINT}" "${HINT_COST}"` - if [ -z "$HINT_ID" ]; then - echo -e "\e[31;01m!!! An error occured during hint import!\e[00m (title=Astuce #1;content=${EXO_HINT};cost=${HINT_COST})" - else - echo -e "\e[32m>>> New hint added:\e[00m $HINT_ID - Astuce #1" + HINTS=$(get_dir "${THM_BASEURI}${EXO_BASEURI}/hints/" | sed -E 's#(.*)#hints/\1#') + [ -z "${HINTS}" ] && HINTS=$(get_dir "${THM_BASEURI}${EXO_BASEURI}/" | grep ^hint.) + [ -z "${HINTS}" ] && HINTS="hint.txt" + HINT_COUNT=1 + echo "${HINTS}" | while read HINT + do + EXO_HINT=$(get_file "${THM_BASEURI}${EXO_BASEURI}/${HINT}") + if [ -n "$EXO_HINT" ]; then + if echo "${EXO_HINT}" | file --mime-type -b - | grep text/ && [ $(echo "${EXO_HINT}" | wc -l) -lt 25 ]; then + HINT_ID=`new_hint "${THEME_ID}" "${EXO_ID}" "Astuce #${HINT_COUNT}" "${EXO_HINT}" "${HINT_COST}"` + else + HINT_ID=`new_hint "${THEME_ID}" "${EXO_ID}" "Astuce #${HINT_COUNT}" "" "${HINT_COST}" "${THM_BASEURI}${EXO_BASEURI}/${HINT}"` + fi + + if [ -z "$HINT_ID" ]; then + echo -e "\e[31;01m!!! An error occured during hint import!\e[00m (title=Astuce #${HINT_COUNT};content=${EXO_HINT};cost=${HINT_COST})" + else + echo -e "\e[32m>>> New hint added:\e[00m $HINT_ID - Astuce #${HINT_COUNT}" + fi fi - fi + HINT_COUNT=$(($HINT_COUNT + 1)) + done # Files: splited diff --git a/frontend/static/views/theme.html b/frontend/static/views/theme.html index 792cf571..af62f802 100644 --- a/frontend/static/views/theme.html +++ b/frontend/static/views/theme.html @@ -35,8 +35,10 @@
    + Télécharger

    {{ hint.title }}

    -

    +

    +

    Utilisez le bouton pour télécharger l'indice.

    Débloquer cet indice vous coûtera .

    diff --git a/libfic/file.go b/libfic/file.go index 5b3e74ed..658f7a22 100644 --- a/libfic/file.go +++ b/libfic/file.go @@ -69,7 +69,7 @@ func (e Exercice) GetFiles() ([]EFile, error) { } } -func (e Exercice) ImportFile(filePath string, origin string, digest []byte) (EFile, error) { +func (e Exercice) ImportFile(filePath string, origin string, digest []byte) (interface{}, error) { if digest == nil && !OptionalDigest { return EFile{}, errors.New("No digest given.") } else if fi, err := os.Stat(filePath); err != nil { @@ -84,7 +84,6 @@ func (e Exercice) ImportFile(filePath string, origin string, digest []byte) (EFi if _, err := io.Copy(hash, reader); err != nil { return EFile{}, err } - result := hash.Sum(nil) if len(digest) != len(result) { diff --git a/libfic/hint.go b/libfic/hint.go index 123d4a02..6dab02b6 100644 --- a/libfic/hint.go +++ b/libfic/hint.go @@ -1,6 +1,8 @@ package fic import ( + "path" + "strings" ) type EHint struct { @@ -11,11 +13,18 @@ type EHint struct { Cost int64 `json:"cost"` } +func treatHintContent(content *string) { + if strings.HasPrefix(*content, "$FILES") { + *content = "$FILES" + path.Join(FilesDir, strings.TrimPrefix(*content, "$FILES")) + } +} + func GetHint(id int64) (EHint, error) { var h EHint if err := DBQueryRow("SELECT id_hint, id_exercice, title, content, cost FROM exercice_hints WHERE id_hint = ?", id).Scan(&h.Id, &h.IdExercice, &h.Title, &h.Content, &h.Cost); err != nil { return h, err } + treatHintContent(&h.Content) return h, nil } @@ -33,6 +42,7 @@ func (e Exercice) GetHints() ([]EHint, error) { if err := rows.Scan(&h.Id, &h.Title, &h.Content, &h.Cost); err != nil { return nil, err } + treatHintContent(&h.Content) hints = append(hints, h) } if err := rows.Err(); err != nil { From 21e4b04c193dcfa0abdba95932d90c00febafdbc Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 14 Jan 2017 15:03:25 +0100 Subject: [PATCH 0381/2518] frontend: dedicate a field in JSON to file hint --- frontend/static/views/theme.html | 20 +++++++++----------- libfic/hint.go | 22 ++++++++++++---------- libfic/team_my.go | 14 +++++++------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/frontend/static/views/theme.html b/frontend/static/views/theme.html index af62f802..d0c8974e 100644 --- a/frontend/static/views/theme.html +++ b/frontend/static/views/theme.html @@ -30,18 +30,16 @@
    Indices
    - +

    +

    Cliquez ici pour télécharger l'indice.

    +

    Débloquer cet indice vous coûtera .

    +
    +
    diff --git a/libfic/hint.go b/libfic/hint.go index 6dab02b6..a47b3501 100644 --- a/libfic/hint.go +++ b/libfic/hint.go @@ -6,16 +6,18 @@ import ( ) type EHint struct { - Id int64 `json:"id"` - IdExercice int64 `json:"idExercice"` - Title string `json:"title"` + Id int64 `json:"id"` + IdExercice int64 `json:"idExercice"` + Title string `json:"title"` Content string `json:"content"` - Cost int64 `json:"cost"` + File string `json:"file"` + Cost int64 `json:"cost"` } -func treatHintContent(content *string) { - if strings.HasPrefix(*content, "$FILES") { - *content = "$FILES" + path.Join(FilesDir, strings.TrimPrefix(*content, "$FILES")) +func treatHintContent(h *EHint) { + if strings.HasPrefix(h.Content, "$FILES") { + h.File = path.Join(FilesDir, strings.TrimPrefix(h.Content, "$FILES")) + h.Content = "" } } @@ -24,7 +26,7 @@ func GetHint(id int64) (EHint, error) { if err := DBQueryRow("SELECT id_hint, id_exercice, title, content, cost FROM exercice_hints WHERE id_hint = ?", id).Scan(&h.Id, &h.IdExercice, &h.Title, &h.Content, &h.Cost); err != nil { return h, err } - treatHintContent(&h.Content) + treatHintContent(&h) return h, nil } @@ -42,7 +44,7 @@ func (e Exercice) GetHints() ([]EHint, error) { if err := rows.Scan(&h.Id, &h.Title, &h.Content, &h.Cost); err != nil { return nil, err } - treatHintContent(&h.Content) + treatHintContent(&h) hints = append(hints, h) } if err := rows.Err(); err != nil { @@ -59,7 +61,7 @@ func (e Exercice) AddHint(title string, content string, cost int64) (EHint, erro } else if hid, err := res.LastInsertId(); err != nil { return EHint{}, err } else { - return EHint{hid, e.Id, title, content, cost}, nil + return EHint{hid, e.Id, title, content, "", cost}, nil } } diff --git a/libfic/team_my.go b/libfic/team_my.go index 6e5404e9..242d0bb0 100644 --- a/libfic/team_my.go +++ b/libfic/team_my.go @@ -14,11 +14,11 @@ type myTeamFile struct { Size int64 `json:"size"` } type myTeamHint struct { - HintId int64 `json:"id"` - Title string `json:"title"` - Content string `json:"content"` - Cost int64 `json:"cost"` - Unlocked bool `json:"unlocked"` + HintId int64 `json:"id"` + Title string `json:"title"` + Content *string `json:"content"` + File *string `json:"file"` + Cost int64 `json:"cost"` } type myTeamExercice struct { ThemeId int `json:"theme_id"` @@ -99,9 +99,9 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) { } else { for _, h := range hints { if t == nil || t.HasHint(h) { - exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, h.Content, h.Cost, true}) + exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, &h.Content, &h.File, h.Cost}) } else { - exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, "", h.Cost, false}) + exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, nil, nil, h.Cost}) } } } From 78ce24f3f720eb465dba7d943ea488ff4d6b5634 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 15 Jan 2017 23:56:28 +0100 Subject: [PATCH 0382/2518] fixup! fixup! WIP esthetic changes --- frontend/static/css/fic.css | 1 - frontend/static/index.html | 4 +-- frontend/static/js/challenge.js | 5 ++-- frontend/static/public.html | 50 ++++++++++++++++++-------------- frontend/static/views/theme.html | 8 ++--- 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/frontend/static/css/fic.css b/frontend/static/css/fic.css index 2f9a7d81..081f0c84 100644 --- a/frontend/static/css/fic.css +++ b/frontend/static/css/fic.css @@ -15,7 +15,6 @@ body { } .navbar #clock { font-size: 70px; - text-align: center; } .point, .expired { transition: color text-shadow 1s; diff --git a/frontend/static/index.html b/frontend/static/index.html index 84c638b4..964d927a 100644 --- a/frontend/static/index.html +++ b/frontend/static/index.html @@ -46,7 +46,7 @@ Epita
    -
    +
    {{ time.hours | time }} : {{ time.minutes | time }} @@ -107,7 +107,7 @@
    diff --git a/frontend/static/js/challenge.js b/frontend/static/js/challenge.js index 6b5d21ee..2dbad794 100644 --- a/frontend/static/js/challenge.js +++ b/frontend/static/js/challenge.js @@ -30,14 +30,12 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"]) }); $locationProvider.html5Mode(true); }) - .run(function($rootScope, $timeout) { + .run(function($rootScope, $interval) { $rootScope.current_theme = 0; $rootScope.current_exercice = 0; $rootScope.time = {}; function updTime() { - $timeout.cancel($rootScope.cbm); - $rootScope.cbm = $timeout(updTime, 1000); if (sessionStorage.userService) { var time = angular.fromJson(sessionStorage.userService); var srv_cur = (Date.now() + (time.cu * 1000 - time.he)) / 1000; @@ -68,6 +66,7 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"]) } } updTime(); + $interval(updTime, 1000); }) .controller("DataController", function($sce, $scope, $http, $rootScope, $timeout) { var actMenu = function() { diff --git a/frontend/static/public.html b/frontend/static/public.html index f3c5411f..b805d76c 100644 --- a/frontend/static/public.html +++ b/frontend/static/public.html @@ -20,7 +20,7 @@ - + -
    +
    +
    - - - - - - + + - - - - + + + + + + + + + + + + + + + +
    Niveau 1Niveau 2Niveau 3Niveau 4Niveau 5
    {{ th.name }}
    {{ themes[th].name }}{{ ex.solved }}{{ ex.tried }}
    Niveau {{ lvl }} + + {{ exercice.solved }} + {{ exercice.tried }} + +
    {{ team.rank }}ere
    {{ team.name }}
    + {{ mystats.themes[tid].solved }}/{{ mystats.themes[tid].total }} + ({{ mystats.themes[tid].tries }}) +
    + Résolus + Total résolus
    + Tentatives +
    + {{ mystats.themes[tid].solved }}
    + {{ mystats.themes[tid].tries }} +
    +
    - +
    +
    @@ -171,31 +156,139 @@ - - - + + +
    PlaceScore
    {{ r.rank }}ere
    {{ r.rank }}ere {{ r.name }} {{ r.score }}
    - - + + -
    +
    -
    +
    +
    {{ e.since | since }}
    - - Epita - + + +
    @@ -209,5 +302,10 @@ + From 416ad65c875229760c71043153181d0b48ef5a5b Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 20 Jan 2017 19:18:43 +0100 Subject: [PATCH 0396/2518] admin: add public interface management --- admin/api/public.go | 80 ++++++++++++++++++++ admin/index.go | 1 + admin/static.go | 3 + admin/static/index.html | 1 + admin/static/js/app.js | 80 ++++++++++++++++++++ admin/static/views/public.html | 129 +++++++++++++++++++++++++++++++++ 6 files changed, 294 insertions(+) create mode 100644 admin/api/public.go create mode 100644 admin/static/views/public.html diff --git a/admin/api/public.go b/admin/api/public.go new file mode 100644 index 00000000..ceccf230 --- /dev/null +++ b/admin/api/public.go @@ -0,0 +1,80 @@ +package api + +import ( + "encoding/json" + "os" + "path" + + "github.com/julienschmidt/httprouter" +) + +func init() { + router.GET("/api/public.json", apiHandler(getPublic)) + router.DELETE("/api/public.json", apiHandler(deletePublic)) + router.PUT("/api/public.json", apiHandler(savePublic)) +} + +type FICPublicScene struct { + Type string `json:"type"` + Params map[string]interface{} `json:"params"` +} + +func readPublic(path string) ([]FICPublicScene, error) { + var s []FICPublicScene + if fd, err := os.Open(path); err != nil { + return s, err + } else { + defer fd.Close() + jdec := json.NewDecoder(fd) + + if err := jdec.Decode(&s); err != nil { + return s, err + } + + return s, nil + } +} + +func savePublicTo(path string, s []FICPublicScene) error { + if fd, err := os.Create(path); err != nil { + return err + } else { + defer fd.Close() + jenc := json.NewEncoder(fd) + + if err := jenc.Encode(s); err != nil { + return err + } + + return nil + } +} + +func getPublic(_ httprouter.Params, body []byte) (interface{}, error) { + if _, err := os.Stat(path.Join(TeamsDir, "_public", "public.json")); !os.IsNotExist(err) { + return readPublic(path.Join(TeamsDir, "_public", "public.json")) + } else { + return []FICPublicScene{}, nil + } +} + +func deletePublic(_ httprouter.Params, body []byte) (interface{}, error) { + if err := savePublicTo(path.Join(TeamsDir, "_public", "public.json"), []FICPublicScene{}); err != nil { + return nil, err + } else { + return []FICPublicScene{}, err + } +} + +func savePublic(_ httprouter.Params, body []byte) (interface{}, error) { + var scenes []FICPublicScene + if err := json.Unmarshal(body, &scenes); err != nil { + return nil, err + } + + if err := savePublicTo(path.Join(TeamsDir, "_public", "public.json"), scenes); err != nil { + return nil, err + } else { + return scenes, err + } +} diff --git a/admin/index.go b/admin/index.go index 85c7448c..7e1270f2 100644 --- a/admin/index.go +++ b/admin/index.go @@ -23,6 +23,7 @@ const indextpl = `
  • Équipes
  • Thèmes
  • Exercices
  • +
  • Public
  • Événements
  • Paramètres
  • diff --git a/admin/static.go b/admin/static.go index ba2bebf5..9d1bb918 100644 --- a/admin/static.go +++ b/admin/static.go @@ -19,6 +19,9 @@ func init() { api.Router().GET("/events/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { http.ServeFile(w, r, path.Join(StaticDir, "index.html")) }) + api.Router().GET("/public", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + http.ServeFile(w, r, path.Join(StaticDir, "index.html")) + }) api.Router().GET("/settings/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { http.ServeFile(w, r, path.Join(StaticDir, "index.html")) }) diff --git a/admin/static/index.html b/admin/static/index.html index dcbd3374..631dd44a 100644 --- a/admin/static/index.html +++ b/admin/static/index.html @@ -21,6 +21,7 @@
  • Équipes
  • Thèmes
  • Exercices
  • +
  • Public
  • Événements
  • Paramètres
  • diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 64a77597..458e49f8 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -37,6 +37,10 @@ angular.module("FICApp", ["ngRoute", "ngResource", "ngSanitize"]) controller: "TeamNewController", templateUrl: "views/team-new.html" }) + .when("/public", { + controller: "PublicController", + templateUrl: "views/public.html" + }) .when("/events", { controller: "EventsListController", templateUrl: "views/event-list.html" @@ -65,6 +69,11 @@ angular.module("FICApp") 'update': {method: 'PUT'}, }) }) + .factory("Scene", function($resource) { + return $resource("/api/public.json", null, { + 'update': {method: 'PUT'}, + }) + }) .factory("Team", function($resource) { return $resource("/api/teams/:teamId", { teamId: '@id' }, { 'update': {method: 'PUT'}, @@ -228,6 +237,77 @@ angular.module("FICApp") } }) + .controller("PublicController", function($scope, Scene, Theme, Teams, Exercice) { + $scope.scenes = Scene.query(); + $scope.themes = Theme.query(); + $scope.teams = Teams.get(); + + $scope.types = { + "welcome": "Messages de bienvenue", + "message": "Message", + "panel": "Boîte", + "exercice": "Exercice", + "table": "Tableau", + "rank": "Classement", + }; + $scope.welcome_types = { + "init": "Accueil des équipes", + "public": "Accueil du public", + "countdown": "Compte à rebours lancement", + }; + $scope.panel_types = { + "panel-default": "Default", + "panel-info": "Info", + "panel-success": "Success", + "panel-warning": "Warning", + "panel-danger": "Danger", + }; + $scope.rank_types = { + "general": "Classement général", + }; + $scope.table_types = { + "levels": "Niveaux d'exercices", + "teams": "Équipes", + }; + $scope.exercices = Exercice.query(); + + $scope.clearScene = function() { + Scene.delete(function() { + $scope.scenes = []; + }); + }; + $scope.saveScenes = function() { + Scene.update($scope.scenes); + }; + $scope.addScene = function() { + $scope.scenes.push({params: {}}); + }; + $scope.delScene = function(s) { + angular.forEach($scope.scenes, function(scene, k) { + if (scene == s) + $scope.scenes.splice(k, 1); + }); + }; + $scope.upScene = function(s) { + angular.forEach($scope.scenes, function(scene, k) { + if (scene == s && k > 0) { + $scope.scenes.splice(k, 1); + $scope.scenes.splice(k - 1, 0, scene); + } + }); + }; + $scope.downScene = function(s) { + var move = true; + angular.forEach($scope.scenes, function(scene, k) { + if (move && scene == s) { + $scope.scenes.splice(k, 1); + $scope.scenes.splice(k + 1, 0, scene); + move = false; + } + }); + }; + }) + .controller("EventsListController", function($scope, Event, $location) { $scope.events = Event.query(); $scope.fields = ["id", "kind", "txt", "time"]; diff --git a/admin/static/views/public.html b/admin/static/views/public.html new file mode 100644 index 00000000..435d30bd --- /dev/null +++ b/admin/static/views/public.html @@ -0,0 +1,129 @@ +
    +

    Interface publique Vider la scène Ajouter un élément +

    + +
    +
    +
    +
    + +
    +
    +
    + Up + Down +
    + +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    From 544bbb745c7289fd8fe367d8861fe011651e7608 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 20 Jan 2017 20:52:31 +0100 Subject: [PATCH 0397/2518] admin: new route /members/ --- admin/api/team.go | 22 ++++++++++++++++++++++ libfic/member.go | 9 +++++++++ 2 files changed, 31 insertions(+) diff --git a/admin/api/team.go b/admin/api/team.go index 828ff18b..5ae6ddee 100644 --- a/admin/api/team.go +++ b/admin/api/team.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "fmt" + "strconv" "strings" "srs.epita.fr/fic-server/libfic" @@ -62,6 +63,9 @@ func init() { router.GET("/api/teams/:tid/name", apiHandler(teamHandler( func(team fic.Team, _ []byte) (interface{}, error) { return team.InitialName, nil }))) + + router.GET("/api/members/:mid/team", apiHandler(dispMemberTeam)) + router.GET("/api/members/:mid/team/name", apiHandler(dispMemberTeamName)) } func nginxGenMember() (string, error) { @@ -149,3 +153,21 @@ func addTeamMember(team fic.Team, body []byte) (interface{}, error) { return team.GetMembers() } + +func dispMemberTeam(ps httprouter.Params, body []byte) (interface{}, error) { + if mid, err := strconv.Atoi(string(ps.ByName("mid"))); err != nil { + return fic.Team{}, err + } else { + return fic.GetMember(mid) + } +} + +func dispMemberTeamName(ps httprouter.Params, body []byte) (interface{}, error) { + if mid, err := strconv.Atoi(string(ps.ByName("mid"))); err != nil { + return nil, err + } else if team, err := fic.GetMember(mid); err != nil { + return nil, err + } else { + return team.InitialName, nil + } +} diff --git a/libfic/member.go b/libfic/member.go index 7dad3c4c..0b4ce660 100644 --- a/libfic/member.go +++ b/libfic/member.go @@ -10,6 +10,15 @@ type Member struct { Company string `json:"company"` } +func GetMember(cnt int) (Team, error) { + var t Team + if err := DBQueryRow("SELECT T.id_team, T.initial_name, T.name, T.color FROM team_members M RIGHT OUTER JOIN teams T ON T.id_team = M.id_team LIMIT ?, 1", cnt - 1).Scan(&t.Id, &t.InitialName, &t.Name, &t.Color); err != nil { + return t, err + } + + return t, nil +} + func (t Team) GetMembers() ([]Member, error) { if rows, err := DBQuery("SELECT id_member, firstname, lastname, nickname, company FROM team_members WHERE id_team = ?", t.Id); err != nil { return nil, err From 318bc4bc4d616907f164ae6f198d8760515ee7c5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 20 Jan 2017 20:53:32 +0100 Subject: [PATCH 0398/2518] Update openssl settings --- admin/pki/openssl.cnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/pki/openssl.cnf b/admin/pki/openssl.cnf index 495674f9..1848365b 100644 --- a/admin/pki/openssl.cnf +++ b/admin/pki/openssl.cnf @@ -101,7 +101,7 @@ emailAddress = optional #################################################################### [ req ] -default_bits = 2048 +default_bits = 4096 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes From 17f51f5e7b45821d0f59135b05b39cf4a410c1d5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:14:28 +0100 Subject: [PATCH 0399/2518] admin: can force page regeneration --- admin/api/settings.go | 2 +- admin/static/js/app.js | 4 ++++ admin/static/views/settings.html | 4 +++- backend/main.go | 6 +++++- settings/settings.go | 1 + 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/admin/api/settings.go b/admin/api/settings.go index 31bc7446..40afef56 100644 --- a/admin/api/settings.go +++ b/admin/api/settings.go @@ -22,7 +22,7 @@ func getSettings(_ httprouter.Params, body []byte) (interface{}, error) { if settings.ExistsSettings(path.Join(TeamsDir, settings.SettingsFile)) { return settings.ReadSettings(path.Join(TeamsDir, settings.SettingsFile)) } else { - return settings.FICSettings{time.Unix(0,0), time.Unix(0,0), fic.FirstBlood, fic.SubmissionCostBase, false, false, false, true, true}, nil + return settings.FICSettings{time.Unix(0,0), time.Unix(0,0), time.Unix(0,0), fic.FirstBlood, fic.SubmissionCostBase, false, false, false, true, true}, nil } } diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 458e49f8..34366490 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -228,6 +228,10 @@ angular.module("FICApp") $location.url("/"); }); } + $scope.regenerate = function() { + this.config.generation = (new Date()).toISOString(); + $scope.saveSettings(); + } $scope.launchChallenge = function() { var ts = Date.now() - Date.now() % 60000; var d = new Date(ts + 120000); diff --git a/admin/static/views/settings.html b/admin/static/views/settings.html index fe15a1dc..97aebc06 100644 --- a/admin/static/views/settings.html +++ b/admin/static/views/settings.html @@ -1,7 +1,9 @@ -

    Paramètres

    +

    Paramètres Regénérer les fichiers statiques

    + +
    diff --git a/backend/main.go b/backend/main.go index b0d660ee..6b458107 100644 --- a/backend/main.go +++ b/backend/main.go @@ -43,8 +43,12 @@ func watchsubdir(watcher *fsnotify.Watcher, pathname string) error { } } +var lastRegeneration time.Time + func reloadSettings(config settings.FICSettings) { - if fic.PartialValidation != config.PartialValidation || fic.UnlockedChallenges != !config.EnableExerciceDepend || fic.FirstBlood != config.FirstBlood || fic.SubmissionCostBase != config.SubmissionCostBase { + if lastRegeneration != config.Generation || fic.PartialValidation != config.PartialValidation || fic.UnlockedChallenges != !config.EnableExerciceDepend || fic.FirstBlood != config.FirstBlood || fic.SubmissionCostBase != config.SubmissionCostBase { + lastRegeneration = config.Generation + fic.PartialValidation = config.PartialValidation fic.UnlockedChallenges = !config.EnableExerciceDepend diff --git a/settings/settings.go b/settings/settings.go index 6775c03c..d327663c 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -15,6 +15,7 @@ const SettingsFile = "settings.json" type FICSettings struct { Start time.Time `json:"start"` End time.Time `json:"end"` + Generation time.Time `json:"generation"` FirstBlood float64 `json:"firstBlood"` SubmissionCostBase float64 `json:"submissionCostBase"` From 4fe641a9f5183a028a39b02cb2893293bac15fa5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:17:21 +0100 Subject: [PATCH 0400/2518] change the way themes are stored in stats --- admin/static/js/app.js | 6 +++++- libfic/team_stats.go | 13 ++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 34366490..34d64d68 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -480,7 +480,11 @@ angular.module("FICApp") $scope.teamstats = TeamStats.get({ teamId: $routeParams.teamId }); $scope.teamstats.$promise.then(function(res) { solvedByLevelPie("#pieLevels", res.levels); - solvedByThemesPie("#pieThemes", res.themes); + var themes = []; + angular.forEach(res.themes, function(theme, tid) { + themes.push(theme); + }) + solvedByThemesPie("#pieThemes", themes); }); }) .controller("TeamExercicesController", function($scope, Teams, Themes, TeamMy, Exercice, $routeParams) { diff --git a/libfic/team_stats.go b/libfic/team_stats.go index a9ef4112..300dbe7b 100644 --- a/libfic/team_stats.go +++ b/libfic/team_stats.go @@ -13,8 +13,8 @@ type statLine struct { } type teamStats struct { - Levels []statLine `json:"levels"` - Themes []statLine `json:"themes"` + Levels []statLine `json:"levels"` + Themes map[int64]statLine `json:"themes"` } func (s *teamStats) GetLevel(level int) *statLine { @@ -38,7 +38,10 @@ func (t Team) GetStats() (interface{}, error) { } func GetTeamsStats(t *Team) (interface{}, error) { - stat := teamStats{} + stat := teamStats{ + []statLine{}, + map[int64]statLine{}, + } if themes, err := GetThemes(); err != nil { return nil, err @@ -84,13 +87,13 @@ func GetTeamsStats(t *Team) (interface{}, error) { } } - stat.Themes = append(stat.Themes, statLine{ + stat.Themes[theme.Id] = statLine{ theme.Name, total, solved, tried, tries, - }) + } } return stat, nil From cab95b79856b3a03586fbb56fb167151b415493b Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:18:05 +0100 Subject: [PATCH 0401/2518] libfic: new function to retrieve exercices from a hint --- libfic/hint.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libfic/hint.go b/libfic/hint.go index a47b3501..d329c692 100644 --- a/libfic/hint.go +++ b/libfic/hint.go @@ -84,3 +84,12 @@ func (h EHint) Delete() (int64, error) { return nb, err } } + +func (h EHint) GetExercice() (Exercice, error) { + var eid int64 + if err := DBQueryRow("SELECT id_exercice FROM exercice_hints WHERE id_hint = ?", h.Id).Scan(&eid); err != nil { + return Exercice{}, err + } + + return GetExercice(eid) +} From cb1fe0847b1f9ad99496bf8e643aeceefddb0a82 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:19:49 +0100 Subject: [PATCH 0402/2518] frontend: move file (on the same partition) instead of open, write, close the final file --- frontend/main.go | 6 ++++-- frontend/save.go | 46 +++++++++++++++++----------------------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/frontend/main.go b/frontend/main.go index 30c6cb31..3c939ef4 100644 --- a/frontend/main.go +++ b/frontend/main.go @@ -17,6 +17,7 @@ const startedFile = "started" var TeamsDir string var SubmissionDir string +var TmpSubmissionDir string var touchTimer *time.Timer = nil @@ -70,10 +71,11 @@ func main() { log.SetPrefix("[frontend] ") SubmissionDir = path.Clean(SubmissionDir) + TmpSubmissionDir = path.Join(SubmissionDir, ".tmp") log.Println("Creating submission directory...") - if _, err := os.Stat(SubmissionDir); os.IsNotExist(err) { - if err := os.MkdirAll(SubmissionDir, 0777); err != nil { + if _, err := os.Stat(TmpSubmissionDir); os.IsNotExist(err) { + if err := os.MkdirAll(TmpSubmissionDir, 0777); err != nil { log.Fatal("Unable to create submission directory: ", err) } } diff --git a/frontend/save.go b/frontend/save.go index 8e87cbc4..bb2009b9 100644 --- a/frontend/save.go +++ b/frontend/save.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "io/ioutil" "log" "net/http" @@ -42,40 +43,27 @@ func saveFile(dirname string, filename string, r *http.Request) error { } } - var f *os.File + // Write content to temp file + tmpfile, err := ioutil.TempFile(TmpSubmissionDir, "") + if err != nil { + return err + } + + writer := bufio.NewWriter(tmpfile) + reader := bufio.NewReader(r.Body) + if _, err := reader.WriteTo(writer); err != nil { + return err + } + writer.Flush() + tmpfile.Close() if filename == "" { - if fd, err := ioutil.TempFile(dirname, ""); err != nil { - return err - } else { - defer f.Close() - f = fd - } - } else { - if fd, err := os.Create(path.Join(dirname, filename)); err != nil { - return err - } else { - defer f.Close() - f = fd - } + filename = path.Base(tmpfile.Name()) } - // Read request body - var body []byte - if r.ContentLength > 0 { - tmp := make([]byte, 1024) - for { - n, err := r.Body.Read(tmp) - for j := 0; j < n; j++ { - body = append(body, tmp[j]) - } - if err != nil || n <= 0 { - break - } - } + if err := os.Rename(tmpfile.Name(), path.Join(dirname, filename)); err != nil { + log.Println("[ERROR] Unable to move file: ", err) } - f.Write(body) - return nil } From c1c84ba3d1b31c4d8f6a1db814ca16166ee8fe59 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:20:20 +0100 Subject: [PATCH 0403/2518] backend: generate an event when a team open an hint --- backend/hint.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/backend/hint.go b/backend/hint.go index 17124f5b..2a074a31 100644 --- a/backend/hint.go +++ b/backend/hint.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "log" "io/ioutil" "os" @@ -28,6 +29,17 @@ func treatOpeningHint(pathname string, team fic.Team) { } else if err := team.OpenHint(hint); err != nil { log.Println("[ERR]", err) } else { + // Write event + if exercice, err := hint.GetExercice(); err != nil { + log.Println("[WRN]", err) + } else if lvl, err := exercice.GetLevel(); err != nil { + log.Println("[WRN]", err) + } else if theme, err := exercice.GetTheme(); err != nil { + log.Println("[WRN]", err) + } else if _, err := fic.NewEvent(fmt.Sprintf("L'équipe %s a dévoilé un indice pour le %de challenge %s !", team.Name, lvl, theme.Name), "alert-info"); err != nil { + log.Println("[WRN] Unable to create event:", err) + } + genTeamMyFile(team) if err := os.Remove(pathname); err != nil { log.Println("[ERR]", err) From da0e7facfddaf5380d56e09bad33f250ecd5bb8a Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:21:21 +0100 Subject: [PATCH 0404/2518] frontend: improve 401 page thank to initial guide --- frontend/static/css/fic.css | 32 ++++++++ frontend/static/welcome.html | 137 ++++++++++++++++++++++++++++++----- 2 files changed, 151 insertions(+), 18 deletions(-) diff --git a/frontend/static/css/fic.css b/frontend/static/css/fic.css index 0c186d5f..14d20d4f 100644 --- a/frontend/static/css/fic.css +++ b/frontend/static/css/fic.css @@ -1,10 +1,42 @@ +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_R.woff') format('woff'); +} +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_RB.woff') format('woff'); + font-weight: bold; +} +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_RI.woff') format('woff'); + font-style: italic; +} + +[ng-cloak] { + display:none !important; +} + body { overflow-y: scroll; } +.beautiful { + font-family: "Linux Biolinum",Helvetica,Arial,sans-serif; +} +.beautiful ol { + font-size: 133%; +} +.beautiful ol ol { + font-size: 90%; +} + .text-bold { font-weight: bolder; } +.text-indent p { + text-indent: 1em; +} .navbar { margin-bottom: 0; diff --git a/frontend/static/welcome.html b/frontend/static/welcome.html index 20ccbbe1..8455c639 100644 --- a/frontend/static/welcome.html +++ b/frontend/static/welcome.html @@ -1,5 +1,5 @@ - + Challenge Forensic @@ -18,22 +18,22 @@ - +

    -
    +
    {{ team.id }}
    -
    +
    - +

    -
    +
    diff --git a/admin/static/views/team-new.html b/admin/static/views/team-new.html deleted file mode 100644 index 8f1f14ee..00000000 --- a/admin/static/views/team-new.html +++ /dev/null @@ -1,11 +0,0 @@ -

    New team

    - -
    - -
    -
    - -
    -
    - -
    From 4a97b065203784da2a55bf22951a50d791beabca Mon Sep 17 00:00:00 2001 From: nemunaire Date: Sat, 4 Nov 2017 15:15:54 +0100 Subject: [PATCH 0430/2518] Set SQL_MODES, waiting https://jira.mariadb.org/browse/MDEV-10426 to be solved --- libfic/db.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfic/db.go b/libfic/db.go index a08dfc00..e10967ea 100644 --- a/libfic/db.go +++ b/libfic/db.go @@ -38,6 +38,9 @@ func DBInit(dsn string) error { if db, err = sql.Open("mysql", dsn + "?parseTime=true&foreign_key_checks=1"); err != nil { return err } + if _, err := db.Exec(`SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';`); err != nil { + return err + } return nil } From 510e25e3515649d6b4c2b4fdee6ed90a120a3fad Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 10 Nov 2017 20:23:08 +0100 Subject: [PATCH 0431/2518] frontend: fix timer location --- frontend/static/public.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/static/public.html b/frontend/static/public.html index 8833201d..4040831f 100644 --- a/frontend/static/public.html +++ b/frontend/static/public.html @@ -179,8 +179,8 @@
    -