From 164b46ece31cf9e290b0fc9acf7dfdd57d2ab75d Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Mon, 14 Mar 2022 22:51:59 +0100 Subject: [PATCH] get rid of session variable in URL Signed-off-by: Michael Kaufmann --- admin_admins.php | 40 +--- admin_autoupdate.php | 27 +-- admin_configfiles.php | 8 +- admin_cronjobs.php | 3 +- admin_customers.php | 53 ++--- admin_domains.php | 9 +- admin_index.php | 88 +++---- admin_ipsandports.php | 9 +- admin_logger.php | 3 +- admin_message.php | 1 - admin_phpsettings.php | 18 +- admin_plans.php | 9 +- admin_settings.php | 12 +- admin_templates.php | 18 +- admin_updates.php | 4 +- customer_domains.php | 12 +- customer_email.php | 27 +-- customer_extras.php | 21 +- customer_ftp.php | 9 +- customer_index.php | 78 ++----- customer_mysql.php | 9 +- index.php | 63 +---- .../updates/froxlor/0.11/update_0.11.inc.php | 69 ++++++ .../updates/froxlor/0.9/update_0.9.inc.php | 1 + lib/Froxlor/Ajax/Ajax.php | 91 ++------ lib/Froxlor/Api/Commands/Customers.php | 6 - lib/Froxlor/CurrentUser.php | 106 +++++++++ lib/Froxlor/UI/Linker.php | 13 +- lib/Froxlor/UI/Paging.php | 17 -- lib/Froxlor/UI/Panel/UI.php | 22 +- lib/Froxlor/UI/Response.php | 16 +- lib/init.php | 221 +++++------------- .../admin/tablelisting.admins.php | 2 + .../admin/tablelisting.customers.php | 2 +- lib/tables.inc.php | 1 - lng/english.lng.php | 1 - logfiles_viewer.php | 3 +- templates/Froxlor/assets/js/main.js | 2 +- templates/Froxlor/base.html.twig | 3 - templates/Froxlor/form/form.html.twig | 1 - .../Froxlor/form/yesnoquestion.html.twig | 1 - templates/Froxlor/misc/version_top.html.twig | 2 +- .../Froxlor/settings/detailpart.html.twig | 1 - .../Froxlor/src/js/components/customer.js | 2 +- .../Froxlor/src/js/components/domains.js | 4 +- .../Froxlor/src/js/components/ipsandports.js | 2 +- .../Froxlor/src/js/components/newsfeed.js | 2 +- templates/Froxlor/src/js/components/search.js | 2 +- .../Froxlor/src/js/components/updatecheck.js | 2 +- templates/Froxlor/src/js/main.js | 1 - templates/Froxlor/table/pagination.html.twig | 12 +- .../Froxlor/user/change_language.html.twig | 1 - .../Froxlor/user/change_password.html.twig | 1 - templates/Froxlor/user/change_theme.html.twig | 1 - templates/Froxlor/userarea.html.twig | 12 +- tests/bootstrap.php | 1 - 56 files changed, 447 insertions(+), 698 deletions(-) create mode 100644 install/updates/froxlor/0.11/update_0.11.inc.php create mode 100644 lib/Froxlor/CurrentUser.php diff --git a/admin_admins.php b/admin_admins.php index f01d86ea..992aa28d 100644 --- a/admin_admins.php +++ b/admin_admins.php @@ -62,33 +62,14 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { $destination_admin = $result['loginname']; if ($destination_admin != '' && $result['adminid'] != $userinfo['userid']) { - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :userid - "); - $result = Database::pexecute_first($result_stmt, array( - 'userid' => $userinfo['userid'] - )); - $s = \Froxlor\Froxlor::genSessionId(); - $ins_stmt = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET - `hash` = :hash, `userid` = :userid, `ipaddress` = :ip, - `useragent` = :ua, `lastactivity` = :la, - `language` = :lang, `adminsession` = '1' - "); - $ins_data = array( - 'hash' => $s, - 'userid' => $id, - 'ip' => $result['ipaddress'], - 'ua' => $result['useragent'], - 'la' => time(), - 'lang' => $result['language'] - ); - Database::pexecute($ins_stmt, $ins_data); + $result['switched_user'] = \Froxlor\CurrentUser::getData(); + $result['adminsession'] = 1; + $result['userid'] = $result['adminid']; + \Froxlor\CurrentUser::setData($result); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "switched adminuser and is now '" . $destination_admin . "'"); - \Froxlor\UI\Response::redirectTo('admin_index.php', array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo('admin_index.php'); } else { \Froxlor\UI\Response::redirectTo('index.php', array( 'action' => 'login' @@ -114,8 +95,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { 'id' => $id ))->delete(); \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('admin_admin_reallydelete', $filename, array( @@ -134,8 +114,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -175,8 +154,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { diff --git a/admin_autoupdate.php b/admin_autoupdate.php index 4442e8c8..5704e323 100644 --- a/admin_autoupdate.php +++ b/admin_autoupdate.php @@ -29,9 +29,8 @@ define('RELEASE_URI', "https://autoupdate.froxlor.org/froxlor-{version}.zip"); define('CHECKSUM_URI', "https://autoupdate.froxlor.org/froxlor-{version}.zip.sha256"); // check for archive-stuff -if (! extension_loaded('zip')) { +if (!extension_loaded('zip')) { \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'error', 'errno' => 2 )); @@ -40,7 +39,6 @@ if (! extension_loaded('zip')) { // 0.11.x requires 7.4 at least if (version_compare("7.4.0", PHP_VERSION, ">=")) { \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'error', 'errno' => 10 )); @@ -72,15 +70,14 @@ if ($page == 'overview') { $message_addinfo = $_message; // not numeric -> error-message - if (! preg_match('/^((\d+\\.)(\d+\\.)(\d+\\.)?(\d+)?(\-(svn|dev|rc)(\d+))?)$/', $_version)) { + if (!preg_match('/^((\d+\\.)(\d+\\.)(\d+\\.)?(\d+)?(\-(svn|dev|rc)(\d+))?)$/', $_version)) { // check for customized version to not output // "There is a newer version of froxlor" besides the error-message \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'error', 'errno' => 3 )); - } elseif (\Froxlor\Froxlor::versionCompare2($version, $_version) == - 1) { + } elseif (\Froxlor\Froxlor::versionCompare2($version, $_version) == -1) { // there is a newer version - yay $isnewerversion = 1; } else { @@ -117,7 +114,7 @@ elseif ($page == 'getdownload') { $toCheck = str_replace('{version}', $newversion, CHECKSUM_URI); // check for local destination folder - if (! is_dir(\Froxlor\Froxlor::getInstallDir() . '/updates/')) { + if (!is_dir(\Froxlor\Froxlor::getInstallDir() . '/updates/')) { mkdir(\Froxlor\Froxlor::getInstallDir() . '/updates/'); } @@ -136,7 +133,6 @@ elseif ($page == 'getdownload') { HttpClient::fileGet($toLoad, $localArchive); } catch (Exception $e) { \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'error', 'errno' => 4 )); @@ -144,7 +140,7 @@ elseif ($page == 'getdownload') { // validate the integrity of the downloaded file $_shouldsum = HttpClient::urlGet($toCheck); - if (! empty($_shouldsum)) { + if (!empty($_shouldsum)) { $_t = explode(" ", $_shouldsum); $shouldsum = $_t[0]; } else { @@ -154,7 +150,6 @@ elseif ($page == 'getdownload') { if ($filesum != $shouldsum) { \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'error', 'errno' => 9 )); @@ -162,13 +157,11 @@ elseif ($page == 'getdownload') { // to the next step \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'extract', 'archive' => basename($localArchive) )); } \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'error', 'errno' => 6 )); @@ -193,21 +186,17 @@ elseif ($page == 'extract') { } else { // error \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'error', 'errno' => 8 )); } // redirect to update-page? - \Froxlor\UI\Response::redirectTo('admin_updates.php', array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo('admin_updates.php'); } - if (! file_exists($localArchive)) { + if (!file_exists($localArchive)) { \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s, 'page' => 'error', 'errno' => 7 )); @@ -231,6 +220,6 @@ elseif ($page == 'error') { // 7 = local archive does not exist // 8 = could not extract archive // 9 = checksum mismatch - // 10 = $s - )); + \Froxlor\UI\Response::redirectTo('admin_configfiles.php'); } $customer_tmpdir = '/tmp/'; @@ -260,9 +258,7 @@ if ($userinfo['change_serversettings'] == '1') { eval("echo \"" . \Froxlor\UI\Template::getTemplate("configfiles/wizard") . "\";"); } } else { - \Froxlor\UI\Response::redirectTo('admin_index.php', array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo('admin_index.php'); } // helper functions diff --git a/admin_cronjobs.php b/admin_cronjobs.php index 67965c68..d017ff9a 100644 --- a/admin_cronjobs.php +++ b/admin_cronjobs.php @@ -64,8 +64,7 @@ if ($page == 'cronjobs' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { diff --git a/admin_customers.php b/admin_customers.php index 5c2b123b..df5837da 100644 --- a/admin_customers.php +++ b/admin_customers.php @@ -34,9 +34,11 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { try { $customer_list_data = include_once dirname(__FILE__) . '/lib/tablelisting/admin/tablelisting.customers.php'; - $collection = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\Customers::class, $userinfo, ['show_usages' => true])) - ->has('admin', \Froxlor\Api\Commands\Admins::class, 'adminid', 'adminid') + $collection = (new \Froxlor\UI\Collection(\Froxlor\Api\Commands\Customers::class, $userinfo, ['show_usages' => true])) ->withPagination($customer_list_data['customer_list']['columns']); + if ($userinfo['change_serversettings']) { + $collection->has('admin', \Froxlor\Api\Commands\Admins::class, 'adminid', 'adminid'); + } } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } @@ -71,33 +73,12 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { if ($result['deactivated'] == '1') { \Froxlor\UI\Response::standard_error("usercurrentlydeactivated", $destination_user); } - $result_stmt = Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :id - AND `hash` = :hash"); - $result = Database::pexecute_first($result_stmt, array( - 'id' => $userinfo['userid'], - 'hash' => $s - )); - $s = \Froxlor\Froxlor::genSessionId(); - $insert = Database::prepare(" - INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET - `hash` = :hash, - `userid` = :id, - `ipaddress` = :ip, - `useragent` = :ua, - `lastactivity` = :lastact, - `language` = :lang, - `adminsession` = '0'"); - Database::pexecute($insert, array( - 'hash' => $s, - 'id' => $id, - 'ip' => $result['ipaddress'], - 'ua' => $result['useragent'], - 'lastact' => time(), - 'lang' => $result['language'] - )); + $result['switched_user'] = \Froxlor\CurrentUser::getData(); + $result['adminsession'] = 0; + $result['userid'] = $result['customerid']; + \Froxlor\CurrentUser::setData($result); + $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "switched user and is now '" . $destination_user . "'"); $target = (isset($_GET['target']) ? $_GET['target'] : 'index'); @@ -105,9 +86,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { if (!file_exists(\Froxlor\Froxlor::getInstallDir() . "/" . $redirect)) { $redirect = "customer_index.php"; } - \Froxlor\UI\Response::redirectTo($redirect, array( - 's' => $s - ), true); + \Froxlor\UI\Response::redirectTo($redirect, null, true); } else { \Froxlor\UI\Response::redirectTo('index.php', array( 'action' => 'login' @@ -132,8 +111,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('customer_reallyunlock', $filename, array( @@ -162,8 +140,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNoWithCheckbox('admin_customer_reallydelete', 'admin_customer_alsoremovefiles', $filename, array( @@ -181,8 +158,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -248,8 +224,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { diff --git a/admin_domains.php b/admin_domains.php index d15e2687..16e92549 100644 --- a/admin_domains.php +++ b/admin_domains.php @@ -92,8 +92,7 @@ if ($page == 'domains' || $page == 'overview') { } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } elseif ($alias_check['count'] > 0) { \Froxlor\UI\Response::standard_error('domains_cantdeletedomainwithaliases'); @@ -119,8 +118,7 @@ if ($page == 'domains' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -376,8 +374,7 @@ if ($page == 'domains' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { diff --git a/admin_index.php b/admin_index.php index 7a11ad90..7e2b5003 100644 --- a/admin_index.php +++ b/admin_index.php @@ -32,25 +32,25 @@ $id = (int) Request::get('id'); if ($action == 'logout') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "logged out"); - - $params = array( - 'adminid' => (int) $userinfo['adminid'] - ); - - if (Settings::Get('session.allow_multiple_login') == '1') { - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :adminid - AND `adminsession` = '1' - AND `hash` = :hash"); - $params['hash'] = $s; - } else { - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :adminid - AND `adminsession` = '1'"); - } - Database::pexecute($stmt, $params); + unset($_SESSION['userinfo']); + \Froxlor\CurrentUser::setData(); + session_destroy(); \Froxlor\UI\Response::redirectTo('index.php'); +} elseif ($action == 'suback') { + if (is_array(\Froxlor\CurrentUser::getField('switched_user'))) { + $result = \Froxlor\CurrentUser::getData(); + $result = $result['switched_user']; + \Froxlor\CurrentUser::setData($result); + $target = (isset($_GET['target']) ? $_GET['target'] : 'index'); + $redirect = "admin_" . $target . ".php"; + if (!file_exists(\Froxlor\Froxlor::getInstallDir() . "/" . $redirect)) { + $redirect = "admin_index.php"; + } + \Froxlor\UI\Response::redirectTo($redirect, null, true); + } else { + \Froxlor\UI\Response::dynamic_error("Cannot change back - You've never switched to another user :-)"); + } } if ($page == 'overview') { @@ -88,7 +88,7 @@ if ($page == 'overview') { $overview['diskspace_bytes'] = $overview['diskspace_assigned'] * 1024; $overview['diskspace_bytes_used'] = $overview['diskspace_used'] * 1024; - $userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1; + $userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : -1; $overview['traffic_bytes'] = $overview['traffic_assigned'] * 1024; $overview['traffic_bytes_used'] = $overview['traffic_used'] * 1024; @@ -114,7 +114,7 @@ if ($page == 'overview') { $isnewerversion = $result['isnewerversion']; } else { $lookfornewversion_lable = $lng['admin']['lookfornewversion']['clickhere']; - $lookfornewversion_link = htmlspecialchars($filename . '?s=' . urlencode($s) . '&page=' . urlencode($page) . '&lookfornewversion=yes'); + $lookfornewversion_link = htmlspecialchars($filename . '?page=' . urlencode($page) . '&lookfornewversion=yes'); $lookfornewversion_message = ''; $lookfornewversion_addinfo = ''; $isnewerversion = 0; @@ -126,7 +126,7 @@ if ($page == 'overview') { // additional sys-infos $meminfo = explode("\n", @file_get_contents("/proc/meminfo")); $memory = ""; - for ($i = 0; $i < count($meminfo); ++ $i) { + for ($i = 0; $i < count($meminfo); ++$i) { if (substr($meminfo[$i], 0, 3) === "Mem") { $memory .= $meminfo[$i] . PHP_EOL; } @@ -137,7 +137,7 @@ if ($page == 'overview') { $load = number_format($loadArray[0], 2, '.', '') . " / " . number_format($loadArray[1], 2, '.', '') . " / " . number_format($loadArray[2], 2, '.', ''); } else { $load = @file_get_contents('/proc/loadavg'); - if (! $load) { + if (!$load) { $load = $lng['admin']['noloadavailable']; } } @@ -191,7 +191,7 @@ if ($page == 'overview') { if (isset($_POST['send']) && $_POST['send'] == 'send') { $old_password = \Froxlor\Validate\Validate::validate($_POST['old_password'], 'old password'); - if (! \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_ADMINS, 'adminid')) { + if (!\Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_ADMINS, 'adminid')) { \Froxlor\UI\Response::standard_error('oldpasswordnotcorrect'); } @@ -229,9 +229,7 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'changed password'); - \Froxlor\UI\Response::redirectTo($filename, Array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } } else { UI::twigBuffer('user/change_password.html.twig'); @@ -251,21 +249,9 @@ if ($page == 'overview') { } catch (Exception $e) { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - - // also update current session - $lng_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_SESSIONS . "` - SET `language`= :lng - WHERE `hash`= :hash"); - Database::pexecute($lng_stmt, array( - 'lng' => $def_language, - 'hash' => $s - )); } $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "changed his/her default language to '" . $def_language . "'"); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } else { $language_options = ''; @@ -294,20 +280,8 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - // also update current session - $theme_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_SESSIONS . "` - SET `theme`= :theme - WHERE `hash`= :hash"); - Database::pexecute($theme_stmt, array( - 'theme' => $theme, - 'hash' => $s - )); - $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "changed his/her theme to '" . $theme . "'"); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } else { $theme_options = ''; @@ -386,22 +360,16 @@ if ($page == 'overview') { // finally remove error from fs @unlink($err_file); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } // show a nice summary of the error-report // before actually sending anything eval("echo \"" . \Froxlor\UI\Template::getTemplate("index/send_error_report") . "\";"); } else { - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } } else { - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } } elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) { require_once __DIR__ . '/api_keys.php'; diff --git a/admin_ipsandports.php b/admin_ipsandports.php index 853bd09e..9244e42b 100644 --- a/admin_ipsandports.php +++ b/admin_ipsandports.php @@ -68,8 +68,7 @@ if ($page == 'ipsandports' || $page == 'overview') { } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('admin_ip_reallydelete', $filename, array( @@ -87,8 +86,7 @@ if ($page == 'ipsandports' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -119,8 +117,7 @@ if ($page == 'ipsandports' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { diff --git a/admin_logger.php b/admin_logger.php index ec40a21f..ea106002 100644 --- a/admin_logger.php +++ b/admin_logger.php @@ -55,8 +55,7 @@ if ($page == 'log' && $userinfo['change_serversettings'] == '1') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('logger_reallytruncate', $filename, array( diff --git a/admin_message.php b/admin_message.php index 300ca125..fd5b427a 100644 --- a/admin_message.php +++ b/admin_message.php @@ -87,7 +87,6 @@ if ($page == 'message') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => $page, - 's' => $s, 'action' => 'showsuccess', 'sentitems' => $mailcounter )); diff --git a/admin_phpsettings.php b/admin_phpsettings.php index f1568b4d..0645de24 100644 --- a/admin_phpsettings.php +++ b/admin_phpsettings.php @@ -61,8 +61,7 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -119,8 +118,7 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('phpsetting_reallydelete', $filename, array( @@ -154,8 +152,7 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -211,8 +208,7 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -253,8 +249,7 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('fpmsetting_reallydelete', $filename, array( @@ -288,8 +283,7 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { diff --git a/admin_plans.php b/admin_plans.php index c2eb9f43..0120187a 100644 --- a/admin_plans.php +++ b/admin_plans.php @@ -71,8 +71,7 @@ if ($page == '' || $page == 'overview') { } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('plan_reallydelete', $filename, array( @@ -93,8 +92,7 @@ if ($page == '' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -164,8 +162,7 @@ if ($page == '' || $page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { diff --git a/admin_settings.php b/admin_settings.php index f5583e56..2a12b1a9 100644 --- a/admin_settings.php +++ b/admin_settings.php @@ -191,9 +191,7 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "wiped all cleartext mail passwords"); Database::query("UPDATE `" . TABLE_MAIL_USERS . "` SET `password` = '';"); Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = '0' WHERE `settinggroup` = 'system' AND `varname` = 'mailpwcleartext'"); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } else { \Froxlor\UI\HTML::askYesNo('admin_cleartextmailpws_reallywipe', $filename, array( 'page' => $page @@ -208,9 +206,7 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { // Set the quota to 0 which means unlimited Database::query("UPDATE `" . TABLE_MAIL_USERS . "` SET `quota` = '0';"); Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `email_quota_used` = '0'"); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } else { \Froxlor\UI\HTML::askYesNo('admin_quotas_reallywipe', $filename, array( 'page' => $page @@ -249,9 +245,7 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') { // Update the Customer, if the used quota is bigger than the allowed quota Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `email_quota` = `email_quota_used` WHERE `email_quota` < `email_quota_used`"); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'enforcing mailquota to all customers: ' . Settings::Get('system.mail_quota') . ' MB'); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } else { \Froxlor\UI\HTML::askYesNo('admin_quotas_reallyenforce', $filename, array( 'page' => $page diff --git a/admin_templates.php b/admin_templates.php index c43505c2..b626b06e 100644 --- a/admin_templates.php +++ b/admin_templates.php @@ -174,8 +174,7 @@ if ($action == '') { )); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "deleted template '" . $result['language'] . ' - ' . $lng['admin']['templates'][str_replace('_subject', '', $result['varname'])] . "'"); \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('admin_template_reallydelete', $filename, array( @@ -210,8 +209,7 @@ if ($action == '') { )); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "deleted template '" . $lng['admin']['templates'][$row['varname']] . "'"); \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('admin_template_reallydelete', $filename, array( @@ -319,8 +317,7 @@ if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "added template '" . $language . ' - ' . $template . "'"); \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } } elseif (isset($_POST['filesend']) && $_POST['filesend'] == 'filesend') { @@ -345,8 +342,7 @@ if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "added template '" . $template . "'"); \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } elseif (!isset($_GET['files'])) { @@ -487,8 +483,7 @@ if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "edited template '" . $result['varname'] . "'"); \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -550,8 +545,7 @@ if ($action == '') { $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "edited template '" . $row['varname'] . "'"); \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { $row = \Froxlor\PhpHelper::htmlentitiesArray($row); diff --git a/admin_updates.php b/admin_updates.php index 90e30e38..66389f0e 100644 --- a/admin_updates.php +++ b/admin_updates.php @@ -62,7 +62,7 @@ if ($page == 'overview') { include_once \Froxlor\Froxlor::getInstallDir() . 'install/updatesql.php'; - $redirect_url = 'admin_index.php?s=' . $s; + $redirect_url = 'admin_index.php'; eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/update_end') . "\";"); \Froxlor\User::updateCounters(); @@ -107,7 +107,7 @@ if ($page == 'overview') { } } else { $success_message = $lng['update']['noupdatesavail']; - $redirect_url = 'admin_index.php?s=' . $s; + $redirect_url = 'admin_index.php'; eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/noupdatesavail') . "\";"); } } diff --git a/customer_domains.php b/customer_domains.php index 38bf4312..b6d4ef18 100644 --- a/customer_domains.php +++ b/customer_domains.php @@ -86,8 +86,7 @@ if ($page == 'overview' || $page == 'domains') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('domains_reallydelete', $filename, array( @@ -108,8 +107,7 @@ if ($page == 'overview' || $page == 'domains') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { $stmt = Database::prepare("SELECT `id`, `domain`, `documentroot`, `ssl_redirect`,`isemaildomain`,`letsencrypt` FROM `" . TABLE_PANEL_DOMAINS . "` @@ -217,8 +215,7 @@ if ($page == 'overview' || $page == 'domains') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { $result['domain'] = $idna_convert->decode($result['domain']); @@ -385,8 +382,7 @@ if ($page == 'overview' || $page == 'domains') { } // back to domain overview \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => 'domains', - 's' => $s + 'page' => 'domains' )); } diff --git a/customer_email.php b/customer_email.php index 43f01e92..9ac4a80f 100644 --- a/customer_email.php +++ b/customer_email.php @@ -91,8 +91,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { if ($result['popaccountid'] != '0') { @@ -119,8 +118,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => $page, 'action' => 'edit', - 'id' => $result['id'], - 's' => $s + 'id' => $result['id'] )); } else { $result_stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "` @@ -225,8 +223,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => $page, 'action' => 'edit', - 'id' => $id, - 's' => $s + 'id' => $id )); } } elseif ($page == 'accounts') { @@ -250,8 +247,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => 'emails', 'action' => 'edit', - 'id' => $id, - 's' => $s + 'id' => $id )); } else { @@ -299,8 +295,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => 'emails', 'action' => 'edit', - 'id' => $id, - 's' => $s + 'id' => $id )); } else { $result['email_full'] = $idna_convert->decode($result['email_full']); @@ -335,8 +330,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => 'emails', 'action' => 'edit', - 'id' => $id, - 's' => $s + 'id' => $id )); } else { $result['email_full'] = $idna_convert->decode($result['email_full']); @@ -371,8 +365,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => 'emails', 'action' => 'edit', - 'id' => $id, - 's' => $s + 'id' => $id )); } else { \Froxlor\UI\HTML::askYesNoWithCheckbox('email_reallydelete_account', 'admin_customer_alsoremovemail', $filename, array( @@ -405,8 +398,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => 'emails', 'action' => 'edit', - 'id' => $id, - 's' => $s + 'id' => $id )); } else { $result['email_full'] = $idna_convert->decode($result['email_full']); @@ -457,8 +449,7 @@ if ($page == 'overview' || $page == 'emails') { \Froxlor\UI\Response::redirectTo($filename, array( 'page' => 'emails', 'action' => 'edit', - 'id' => $id, - 's' => $s + 'id' => $id )); } else { \Froxlor\UI\HTML::askYesNo('email_reallydelete_forwarder', $filename, array( diff --git a/customer_extras.php b/customer_extras.php index f261b5bd..fcabe8f3 100644 --- a/customer_extras.php +++ b/customer_extras.php @@ -81,8 +81,7 @@ if ($page == 'overview' || $page == 'htpasswds') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { if (strpos($result['path'], $userinfo['documentroot']) === 0) { @@ -104,8 +103,7 @@ if ($page == 'overview' || $page == 'htpasswds') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); @@ -136,8 +134,7 @@ if ($page == 'overview' || $page == 'htpasswds') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { if (strpos($result['path'], $userinfo['documentroot']) === 0) { @@ -203,8 +200,7 @@ if ($page == 'overview' || $page == 'htpasswds') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNo('extras_reallydelete_pathoptions', $filename, array( @@ -222,8 +218,7 @@ if ($page == 'overview' || $page == 'htpasswds') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid']); @@ -255,8 +250,7 @@ if ($page == 'overview' || $page == 'htpasswds') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { if (strpos($result['path'], $userinfo['documentroot']) === 0) { @@ -295,8 +289,7 @@ if ($page == 'overview' || $page == 'htpasswds') { \Froxlor\UI\Response::standard_success('backupaborted'); \Froxlor\UI\Response::redirectTo($filename, array( 'page' => $page, - 'action' => '', - 's' => $s + 'action' => '' )); } if ($action == '') { diff --git a/customer_ftp.php b/customer_ftp.php index 1efeebe2..5b7e5583 100644 --- a/customer_ftp.php +++ b/customer_ftp.php @@ -75,8 +75,7 @@ if ($page == 'overview' || $page == 'accounts') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { \Froxlor\UI\HTML::askYesNoWithCheckbox('ftp_reallydelete', 'admin_customer_alsoremoveftphomedir', $filename, array( @@ -97,8 +96,7 @@ if ($page == 'overview' || $page == 'accounts') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { $pathSelect = \Froxlor\FileDir::makePathfield($userinfo['documentroot'], $userinfo['guid'], $userinfo['guid'], '/'); @@ -153,8 +151,7 @@ if ($page == 'overview' || $page == 'accounts') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { if (strpos($result['homedir'], $userinfo['documentroot']) === 0) { diff --git a/customer_index.php b/customer_index.php index cde66a99..a0ab94dd 100644 --- a/customer_index.php +++ b/customer_index.php @@ -27,23 +27,25 @@ use Froxlor\UI\Panel\UI; if ($action == 'logout') { $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, 'logged out'); - $params = array( - "customerid" => $userinfo['customerid'] - ); - if (Settings::Get('session.allow_multiple_login') == '1') { - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :customerid - AND `adminsession` = '0' - AND `hash` = :hash"); - $params["hash"] = $s; - } else { - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :customerid - AND `adminsession` = '0'"); - } - Database::pexecute($stmt, $params); + unset($_SESSION['userinfo']); + \Froxlor\CurrentUser::setData(); + session_destroy(); \Froxlor\UI\Response::redirectTo('index.php'); +} elseif ($action == 'suback') { + if (is_array(\Froxlor\CurrentUser::getField('switched_user'))) { + $result = \Froxlor\CurrentUser::getData(); + $result = $result['switched_user']; + \Froxlor\CurrentUser::setData($result); + $target = (isset($_GET['target']) ? $_GET['target'] : 'index'); + $redirect = "admin_" . $target . ".php"; + if (!file_exists(\Froxlor\Froxlor::getInstallDir() . "/" . $redirect)) { + $redirect = "admin_index.php"; + } + \Froxlor\UI\Response::redirectTo($redirect, null, true); + } else { + \Froxlor\UI\Response::dynamic_error("Cannot change back - You've never switched to another user :-)"); + } } if ($page == 'overview') { @@ -92,7 +94,7 @@ if ($page == 'overview') { // get everything in bytes for the percentage calculation on the dashboard $userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1; - $userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1; + $userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : -1; $userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024; if ($usages) { @@ -109,13 +111,12 @@ if ($page == 'overview') { 'stdsubdomain' => $stdsubdomain ]); UI::twigOutputBuffer(); - } elseif ($page == 'change_password') { if (isset($_POST['send']) && $_POST['send'] == 'send') { $old_password = \Froxlor\Validate\Validate::validate($_POST['old_password'], 'old password'); - if (! \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_CUSTOMERS, 'customerid')) { + if (!\Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_CUSTOMERS, 'customerid')) { \Froxlor\UI\Response::standard_error('oldpasswordnotcorrect'); } @@ -187,9 +188,7 @@ if ($page == 'overview') { Database::pexecute($stmt, $params); } - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } } else { eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/change_password') . "\";"); @@ -207,19 +206,9 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - // also update current session - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_SESSIONS . "` - SET `language` = :lang - WHERE `hash` = :hash"); - Database::pexecute($stmt, array( - "lang" => $def_language, - "hash" => $s - )); } $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "changed default language to '" . $def_language . "'"); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } else { $default_lang = Settings::Get('panel.standardlanguage'); if ($userinfo['def_language'] != '') { @@ -245,19 +234,8 @@ if ($page == 'overview') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } - // also update current session - $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_SESSIONS . "` - SET `theme` = :theme - WHERE `hash` = :hash"); - Database::pexecute($stmt, array( - "theme" => $theme, - "hash" => $s - )); - $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "changed default theme to '" . $theme . "'"); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } else { $default_theme = Settings::Get('panel.default_theme'); if ($userinfo['theme'] != '') { @@ -333,22 +311,16 @@ if ($page == 'overview') { // finally remove error from fs @unlink($err_file); - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } // show a nice summary of the error-report // before actually sending anything eval("echo \"" . \Froxlor\UI\Template::getTemplate("index/send_error_report") . "\";"); } else { - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } } else { - \Froxlor\UI\Response::redirectTo($filename, array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo($filename); } } elseif ($page == 'apikeys' && Settings::Get('api.enabled') == 1) { require_once __DIR__ . '/api_keys.php'; diff --git a/customer_mysql.php b/customer_mysql.php index e8e94648..101960d4 100644 --- a/customer_mysql.php +++ b/customer_mysql.php @@ -101,8 +101,7 @@ if ($page == 'overview' || $page == 'mysqls') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { $dbnamedesc = $result['databasename']; @@ -125,8 +124,7 @@ if ($page == 'overview' || $page == 'mysqls') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { @@ -167,8 +165,7 @@ if ($page == 'overview' || $page == 'mysqls') { \Froxlor\UI\Response::dynamic_error($e->getMessage()); } \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => $page, - 's' => $s + 'page' => $page )); } else { diff --git a/index.php b/index.php index a487df64..7976947d 100644 --- a/index.php +++ b/index.php @@ -28,16 +28,6 @@ if ($action == '') { $action = 'login'; } -if (session_status() == PHP_SESSION_NONE) { - ini_set("session.name", "s"); - ini_set("url_rewriter.tags", ""); - ini_set("session.use_cookies", false); - ini_set("session.cookie_httponly", true); - ini_set("session.cookie_secure", UI::$SSL_REQ); - session_id('login'); - session_start(); -} - if ($action == '2fa_entercode') { // page for entering the 2FA code after successful login if (!isset($_SESSION) || !isset($_SESSION['secret_2fa'])) { @@ -683,10 +673,11 @@ if ($action == 'resetpwd') { function finishLogin($userinfo) { - global $version, $dbversion, $remote_addr, $http_user_agent, $languages; + global $languages; if (isset($userinfo['userid']) && $userinfo['userid'] != '') { - $s = \Froxlor\Froxlor::genSessionId(); + + \Froxlor\CurrentUser::setData($userinfo); if (isset($_POST['language'])) { $language = \Froxlor\Validate\Validate::validate($_POST['language'], 'language'); @@ -698,65 +689,23 @@ function finishLogin($userinfo) } else { $language = Settings::Get('panel.standardlanguage'); } + \Froxlor\CurrentUser::setField('language', $language); if (isset($userinfo['theme']) && $userinfo['theme'] != '') { $theme = $userinfo['theme']; } else { $theme = Settings::Get('panel.default_theme'); + \Froxlor\CurrentUser::setField('theme', $theme); } - if (Settings::Get('session.allow_multiple_login') != '1') { - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `userid` = :uid - AND `adminsession` = :adminsession"); - Database::pexecute($stmt, array( - "uid" => $userinfo['userid'], - "adminsession" => $userinfo['adminsession'] - )); - } - - // check for field 'theme' in session-table, refs #607 - // Changed with #1287 to new method - $stmt = Database::query("SHOW COLUMNS FROM panel_sessions LIKE 'theme'"); - while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { - if ($row['Field'] == "theme") { - $has_theme = true; - } - } - - $params = array( - "hash" => $s, - "userid" => $userinfo['userid'], - "ipaddress" => $remote_addr, - "useragent" => $http_user_agent, - "lastactivity" => time(), - "language" => $language, - "adminsession" => $userinfo['adminsession'] - ); - - if ($has_theme) { - $params["theme"] = $theme; - $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_SESSIONS . "` - (`hash`, `userid`, `ipaddress`, `useragent`, `lastactivity`, `language`, `adminsession`, `theme`) - VALUES (:hash, :userid, :ipaddress, :useragent, :lastactivity, :language, :adminsession, :theme)"); - } else { - $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_SESSIONS . "` - (`hash`, `userid`, `ipaddress`, `useragent`, `lastactivity`, `language`, `adminsession`) - VALUES (:hash, :userid, :ipaddress, :useragent, :lastactivity, :language, :adminsession)"); - } - Database::pexecute($stmt, $params); - $qryparams = array(); if (isset($_POST['qrystr']) && $_POST['qrystr'] != "") { parse_str(urldecode($_POST['qrystr']), $qryparams); } - $qryparams['s'] = $s; if ($userinfo['adminsession'] == '1') { if (\Froxlor\Froxlor::hasUpdates() || \Froxlor\Froxlor::hasDbUpdates()) { - \Froxlor\UI\Response::redirectTo('admin_updates.php', array( - 's' => $s - )); + \Froxlor\UI\Response::redirectTo('admin_updates.php'); } else { if (isset($_POST['script']) && $_POST['script'] != "") { if (preg_match("/customer\_/", $_POST['script']) === 1) { diff --git a/install/updates/froxlor/0.11/update_0.11.inc.php b/install/updates/froxlor/0.11/update_0.11.inc.php new file mode 100644 index 00000000..b3c4bb41 --- /dev/null +++ b/install/updates/froxlor/0.11/update_0.11.inc.php @@ -0,0 +1,69 @@ + (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Install + * + */ +if (!defined('_CRON_UPDATE')) { + if (!defined('AREA') || (defined('AREA') && AREA != 'admin') || !isset($userinfo['loginname']) || (isset($userinfo['loginname']) && $userinfo['loginname'] == '')) { + header('Location: ../../../../index.php'); + exit(); + } +} + +// last 0.10.x release +if (\Froxlor\Froxlor::isFroxlorVersion('0.10.99')) { + showUpdateStep("Updating from 0.10.99 to 0.11.0-rc1", false); + + showUpdateStep("Removing unused table"); + Database::query("DROP TABLE IF EXISTS `panel_sessions`;"); + lastStepStatus(0); + + showUpdateStep("Updating froxlor - theme"); + Database::query("UPDATE `" . TABLE_PANEL_ADMINS . "` SET `theme` = 'Froxlor' WHERE `theme` <> 'Froxlor';"); + Database::query("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `theme` = 'Froxlor' WHERE `theme` <> 'Froxlor';"); + Settings::Set('panel.default_theme', 'Froxlor'); + lastStepStatus(0); + + showUpdateStep("Cleaning up old files"); + $to_clean = array( + "templates/Sparkle", + ); + $disabled = explode(',', ini_get('disable_functions')); + $exec_allowed = ! in_array('exec', $disabled); + $del_list = ""; + foreach ($to_clean as $filedir) { + $complete_filedir = \Froxlor\Froxlor::getInstallDir() . $filedir; + if (file_exists($complete_filedir)) { + if ($exec_allowed) { + Froxlor\FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir)); + } else { + $del_list .= "rm -rf " . escapeshellarg($complete_filedir) . PHP_EOL; + } + } + } + if ($exec_allowed) { + lastStepStatus(0); + } else { + if (empty($del_list)) { + // none of the files existed + lastStepStatus(0); + } else { + lastStepStatus(1, 'manual commands needed'); + echo 'Please run the following commands manually:
' . $del_list . '

'; + } + } +} diff --git a/install/updates/froxlor/0.9/update_0.9.inc.php b/install/updates/froxlor/0.9/update_0.9.inc.php index 156541f3..5a8d8f92 100644 --- a/install/updates/froxlor/0.9/update_0.9.inc.php +++ b/install/updates/froxlor/0.9/update_0.9.inc.php @@ -23,6 +23,7 @@ if (! defined('_CRON_UPDATE')) { } } +define('TABLE_PANEL_SESSIONS', 'panel_sessions'); if (\Froxlor\Froxlor::isFroxlorVersion('0.9-r0')) { showUpdateStep("Updating from 0.9-r0 to 0.9-r1", false); diff --git a/lib/Froxlor/Ajax/Ajax.php b/lib/Froxlor/Ajax/Ajax.php index 20204a34..177a072f 100644 --- a/lib/Froxlor/Ajax/Ajax.php +++ b/lib/Froxlor/Ajax/Ajax.php @@ -27,7 +27,6 @@ use Froxlor\UI\Request; */ class Ajax { - protected string $session; protected string $action; protected string $theme; protected array $userinfo; @@ -38,22 +37,11 @@ class Ajax */ public function __construct() { - $this->session = $_GET['s'] ?? $_POST['s'] ?? null; $this->action = $_GET['action'] ?? $_POST['action'] ?? null; $this->theme = $_GET['theme'] ?? 'Froxlor'; UI::sendHeaders(); UI::sendSslHeaders(); - - ini_set("session.name", "s"); - ini_set("url_rewriter.tags", ""); - ini_set("session.use_cookies", false); - ini_set("session.cookie_httponly", true); - ini_set("session.cookie_secure", UI::$SSL_REQ); - session_id($this->session); - session_start(); - - $this->initLang(); } /** @@ -77,11 +65,11 @@ class Ajax // ensure that we can display messages $language = \Froxlor\Settings::Get('panel.standardlanguage'); - if (isset($this->user_data['language']) && isset($langs[$this->user_data['language']])) { + if (isset($this->userinfo['language']) && isset($langs[$this->userinfo['language']])) { // default: use language from session, #277 - $language = $this->user_data['language']; - } elseif (isset($this->user_data['def_language'])) { - $language = $this->user_data['def_language']; + $language = $this->userinfo['language']; + } elseif (isset($this->userinfo['def_language'])) { + $language = $this->userinfo['def_language']; } // include every english language file we can get @@ -112,6 +100,8 @@ class Ajax { $this->userinfo = $this->getValidatedSession(); + $this->initLang(); + switch ($this->action) { case 'newsfeed': return $this->getNewsfeed(); @@ -139,51 +129,10 @@ class Ajax */ private function getValidatedSession(): array { - $remote_addr = $_SERVER['REMOTE_ADDR']; - if (empty($_SERVER['HTTP_USER_AGENT'])) { - $http_user_agent = 'unknown'; - } else { - $http_user_agent = $_SERVER['HTTP_USER_AGENT']; + if (\Froxlor\CurrentUser::hasSession() == false) { + throw new Exception("No valid session"); } - - $timediff = time() - \Froxlor\Settings::Get('session.sessiontimeout'); - $sel_stmt = \Froxlor\Database\Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_SESSIONS . "` - WHERE `hash` = :hash AND `ipaddress` = :ipaddr AND `useragent` = :ua AND `lastactivity` > :timediff - "); - - $session = \Froxlor\Database\Database::pexecute_first($sel_stmt, [ - 'hash' => $this->session, - 'ipaddr' => $remote_addr, - 'ua' => $http_user_agent, - 'timediff' => $timediff - ]); - - if (!$session) { - throw new Exception('Session is not defined!'); - } - - if ($session['adminsession'] == 1) { - // test for admin - $sel_stmt = \Froxlor\Database\Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_ADMINS . "` - WHERE `adminid` = :userid - "); - } else { - // test for customer - $sel_stmt = \Froxlor\Database\Database::prepare(" - SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` - WHERE `customerid` = :userid - "); - } - $user = \Froxlor\Database\Database::pexecute_first($sel_stmt, [ - 'userid' => $session['userid'] - ]); - if (!$user) { - throw new Exception('Session is not defined!'); - } - $user['adminsession'] = $session['adminsession']; - return $user; + return \Froxlor\CurrentUser::getData(); } /** @@ -252,21 +201,17 @@ class Ajax private function getUpdateCheck() { UI::initTwig(); - UI::twig()->addGlobal('s', $this->session); - // TODO: set variables from current session try { - $json_result = \Froxlor\Api\Commands\Froxlor::getLocal([ - 'adminid' => 1, - 'adminsession' => 1, - 'change_serversettings' => 1, - 'loginname' => 'updatecheck' - ])->checkUpdate(); + $json_result = \Froxlor\Api\Commands\Froxlor::getLocal($this->userinfo)->checkUpdate(); $result = json_decode($json_result, true)['data']; echo UI::twig()->render($this->theme . '/misc/version_top.html.twig', $result); exit; } catch (Exception $e) { - \Froxlor\UI\Response::dynamic_error($e->getMessage()); + // don't display anything if just not allowed due to permissions + if ($e->getCode() != 403) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } } } @@ -310,7 +255,7 @@ class Ajax } $result['settings'][] = [ 'title' => (is_array($sresult['label']) ? $sresult['label']['title'] : $sresult['label']), - 'href' => 'admin_settings.php?page=overview&part=' . $pk[1] . '&em=' . $pk[3] . '&s=' . $this->session + 'href' => 'admin_settings.php?page=overview&part=' . $pk[1] . '&em=' . $pk[3] ]; } } @@ -346,7 +291,7 @@ class Ajax } $result['customer'][] = [ 'title' => User::getCorrectFullUserDetails($cresult), - 'href' => 'admin_customers.php?page=customers&action=edit&id=' . $cresult['customerid'] . '&s=' . $this->session + 'href' => 'admin_customers.php?page=customers&action=edit&id=' . $cresult['customerid'] ]; } } @@ -374,7 +319,7 @@ class Ajax } $result['domains'][] = [ 'title' => $cresult['domain_ace'], - 'href' => 'admin_domains.php?page=domains&action=edit&id=' . $cresult['id'] . '&s=' . $this->session + 'href' => 'admin_domains.php?page=domains&action=edit&id=' . $cresult['id'] ]; } } @@ -403,7 +348,7 @@ class Ajax } $result['domains'][] = [ 'title' => $cresult['domain_ace'], - 'href' => 'customer_domains.php?page=domains&action=edit&id=' . $cresult['id'] . '&s=' . $this->session + 'href' => 'customer_domains.php?page=domains&action=edit&id=' . $cresult['id'] ]; } } diff --git a/lib/Froxlor/Api/Commands/Customers.php b/lib/Froxlor/Api/Commands/Customers.php index c2e03e14..0b31e56f 100644 --- a/lib/Froxlor/Api/Commands/Customers.php +++ b/lib/Froxlor/Api/Commands/Customers.php @@ -1535,12 +1535,6 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource 'id' => $id ), true, true); - // delete potential existing sessions - $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :id AND `adminsession` = '0'"); - Database::pexecute($stmt, array( - 'id' => $id - ), true, true); - // delete traffic information $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TRAFFIC . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( diff --git a/lib/Froxlor/CurrentUser.php b/lib/Froxlor/CurrentUser.php new file mode 100644 index 00000000..7b980d03 --- /dev/null +++ b/lib/Froxlor/CurrentUser.php @@ -0,0 +1,106 @@ + 0 && empty(self::getField('customerid'))); + } + + /** + * return content of a given field from userinfo-array + * + * @param string $index + * + * @return string|array + */ + public static function getField(string $index) + { + return isset($_SESSION['userinfo'][$index]) ? $_SESSION['userinfo'][$index] : ""; + } + + /** + * set userinfo field in session + * + * @param string $index + * @param mixed $data + * + * @return boolean + */ + public static function setField(string $index, $data): bool + { + $_SESSION['userinfo'][$index] = $data; + return true; + } + + /** + * Return userinfo array + * + * @return array + */ + public static function getData(): array + { + return $_SESSION['userinfo'] ?? []; + } + + /** + * re-read in the user data if a valid session exists + * + * @return boolean + */ + public static function reReadUserData() + { + $table = self::isAdmin() ? TABLE_PANEL_ADMINS : TABLE_PANEL_CUSTOMERS; + $userinfo_stmt = Database::prepare(" + SELECT * FROM `" . $table . "` WHERE `loginname`= :loginname AND `deactivated` = '0' + "); + $userinfo = Database::pexecute_first($userinfo_stmt, [ + "loginname" => self::getField('loginname') + ]); + if ($userinfo) { + // dont just set the data, we need to merge with current data + // array_merge is a right-reduction - value existing in getData() will be overwritten with $userinfo, + // other than the union-operator (+) which would keep the values already existing from getData() + $newuserinfo = array_merge(self::getData(), $userinfo); + self::setData($newuserinfo); + return true; + } + // unset / logout + unset($_SESSION['userinfo']); + self::setData([]); + return false; + } +} diff --git a/lib/Froxlor/UI/Linker.php b/lib/Froxlor/UI/Linker.php index a1b2a184..5e2494df 100644 --- a/lib/Froxlor/UI/Linker.php +++ b/lib/Froxlor/UI/Linker.php @@ -1,4 +1,5 @@ protocol = $protocol; @@ -42,8 +43,6 @@ class Linker $this->hostname = $hostname; $this->port = $port; $this->filename = $file; - // @TODO: Remove this - $this->args['s'] = $sessionid; } public function __set($key, $value) @@ -90,11 +89,7 @@ class Linker public function delAll() { // Just resetting the array - // Until the sessionid can be removed: save it - // @TODO: Remove this - $this->args = array( - 's' => $this->args['s'] - ); + $this->args = []; } public function getLink() @@ -158,7 +153,7 @@ class Linker // Loop through arguments and add them to the link foreach ($this->args as $key => $value) { // For all but the first argument, prepend "&" - if (substr($link, - 1) != "?") { + if (substr($link, -1) != "?") { $link .= "&"; } diff --git a/lib/Froxlor/UI/Paging.php b/lib/Froxlor/UI/Paging.php index 0ea498c9..a4b7950f 100644 --- a/lib/Froxlor/UI/Paging.php +++ b/lib/Froxlor/UI/Paging.php @@ -210,23 +210,6 @@ class Paging } $this->userinfo['lastpaging']['pageno'] = $this->pageno; - $upd_stmt = \Froxlor\Database\Database::prepare(" - UPDATE `" . TABLE_PANEL_SESSIONS . "` SET - `lastpaging` = :lastpaging - WHERE `hash` = :hash AND `userid` = :userid - AND `ipaddress` = :ipaddr AND `useragent` = :ua - AND `adminsession` = :adminsession - "); - $upd_data = array( - 'lastpaging' => json_encode($this->userinfo['lastpaging']), - 'hash' => $userinfo['hash'], - 'userid' => $userinfo['userid'], - 'ipaddr' => $userinfo['ipaddress'], - 'ua' => $userinfo['useragent'], - 'adminsession' => $userinfo['adminsession'] - ); - \Froxlor\Database\Database::pexecute($upd_stmt, $upd_data); - $this->limit = $limit; } diff --git a/lib/Froxlor/UI/Panel/UI.php b/lib/Froxlor/UI/Panel/UI.php index 6b820340..110c0a7d 100644 --- a/lib/Froxlor/UI/Panel/UI.php +++ b/lib/Froxlor/UI/Panel/UI.php @@ -51,13 +51,27 @@ class UI private static $install_mode = false; - public static $SSL_REQ = false; - /** * send various security related headers */ public static function sendHeaders() { + $isHttps = + $_SERVER['HTTPS'] + ?? $_SERVER['REQUEST_SCHEME'] + ?? $_SERVER['HTTP_X_FORWARDED_PROTO'] + ?? null; + + $isHttps = + $isHttps && (strcasecmp('on', $isHttps) == 0 + || strcasecmp('https', $isHttps) == 0 + ); + + ini_set("url_rewriter.tags", ""); + ini_set("session.cookie_httponly", true); + ini_set("session.cookie_secure", $isHttps); + session_start(); + header("Content-Type: text/html; charset=UTF-8"); // prevent Froxlor pages from being cached @@ -96,7 +110,6 @@ class UI * If Froxlor was called via HTTPS -> enforce it for the next time by settings HSTS header according to settings */ if (isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) { - self::$SSL_REQ = true; $maxage = \Froxlor\Settings::Get('system.hsts_maxage'); if (empty($maxage)) { $maxage = 0; @@ -161,15 +174,14 @@ class UI if (!self::$install_mode) { // system default if (\Froxlor\Froxlor::DBVERSION <= 202299999) { + // @fixme set this to the last 0.10.x DBVERSION to fallback to the new theme \Froxlor\Settings::Set('panel.default_theme', 'Froxlor'); } $theme = (\Froxlor\Settings::Get('panel.default_theme') !== null) ? \Froxlor\Settings::Get('panel.default_theme') : $theme; // customer theme - /* if (\Froxlor\CurrentUser::hasSession() && \Froxlor\CurrentUser::getField('theme') != $theme) { $theme = \Froxlor\CurrentUser::getField('theme'); } - */ } if (!file_exists(\Froxlor\Froxlor::getInstallDir() . '/templates/' . $theme)) { \Froxlor\PhpHelper::phpErrHandler(E_USER_WARNING, "Theme '" . $theme . "' could not be found.", __FILE__, __LINE__, null); diff --git a/lib/Froxlor/UI/Response.php b/lib/Froxlor/UI/Response.php index fa4b18dc..198ebef5 100644 --- a/lib/Froxlor/UI/Response.php +++ b/lib/Froxlor/UI/Response.php @@ -20,14 +20,8 @@ class Response */ public static function redirectTo($destination, $get_variables = null, $isRelative = true) { - global $s; - if (is_array($get_variables)) { - if (isset($get_variables['s'])) { - $linker = new Linker($destination, $get_variables['s']); - } else { - $linker = new Linker($destination, $s); - } + $linker = new Linker($destination); foreach ($get_variables as $key => $value) { $linker->add($key, $value); @@ -165,7 +159,7 @@ class Response */ public static function standard_success($success_message = '', $replacer = '', $params = array(), $throw_exception = false) { - global $s, $lng; + global $lng; if (isset($lng['success'][$success_message])) { $success_message = strtr($lng['success'][$success_message], array( @@ -178,12 +172,14 @@ class Response } if (is_array($params) && isset($params['filename'])) { - $redirect_url = $params['filename'] . '?s=' . $s; + $redirect_url = $params['filename']; unset($params['filename']); + $first = true; foreach ($params as $varname => $value) { if ($value != '') { - $redirect_url .= '&' . $varname . '=' . $value; + $redirect_url .= ($first ? '?' : '&') . $varname . '=' . $value; + if ($first) $first = false; } } } else { diff --git a/lib/init.php b/lib/init.php index c82a8320..09a74ec1 100644 --- a/lib/init.php +++ b/lib/init.php @@ -20,43 +20,39 @@ // define default theme for configurehint, etc. $_deftheme = 'Froxlor'; -function view($template, $attributes) { - $view = file_get_contents(dirname(__DIR__) . '/templates/' . $template); +function view($template, $attributes) +{ + $view = file_get_contents(dirname(__DIR__) . '/templates/' . $template); - return str_replace(array_keys($attributes), array_values($attributes), $view); + return str_replace(array_keys($attributes), array_values($attributes), $view); } // validate correct php version if (version_compare("7.4.0", PHP_VERSION, ">=")) { - die( - view($_deftheme . '/misc/phprequirementfailed.html.twig', [ - '{{ basehref }}' => '', - '{{ froxlor_min_version }}' => '7.4.0', - '{{ current_version }}' => PHP_VERSION, - '{{ current_year }}' => date('Y', time()), - ]) - ); + die(view($_deftheme . '/misc/phprequirementfailed.html.twig', [ + '{{ basehref }}' => '', + '{{ froxlor_min_version }}' => '7.4.0', + '{{ current_version }}' => PHP_VERSION, + '{{ current_year }}' => date('Y', time()), + ])); } // validate vendor autoloader if (!file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { - die( - view($_deftheme . '/misc/vendormissinghint.html.twig', [ - '{{ basehref }}' => '', - '{{ froxlor_install_dir }}' => dirname(__DIR__), - '{{ current_year }}' => date('Y', time()), - ]) - ); + die(view($_deftheme . '/misc/vendormissinghint.html.twig', [ + '{{ basehref }}' => '', + '{{ froxlor_install_dir }}' => dirname(__DIR__), + '{{ current_year }}' => date('Y', time()), + ])); } require dirname(__DIR__) . '/vendor/autoload.php'; use Froxlor\Database\Database; -use Froxlor\PhpHelper; use Froxlor\Settings; use Froxlor\UI\Panel\UI; use Froxlor\UI\Request; -use voku\helper\AntiXSS; +use Froxlor\CurrentUser; // include MySQL-tabledefinitions require \Froxlor\Froxlor::getInstallDir() . '/lib/tables.inc.php'; @@ -64,7 +60,6 @@ require \Froxlor\Froxlor::getInstallDir() . '/lib/tables.inc.php'; UI::sendHeaders(); UI::initTwig(); - /** * Register Globals Security Fix */ @@ -120,97 +115,12 @@ UI::sendSslHeaders(); // create a new idna converter $idna_convert = new \Froxlor\Idna\IdnaWrapper(); -// SESSION MANAGEMENT -$remote_addr = $_SERVER['REMOTE_ADDR']; - -if (empty($_SERVER['HTTP_USER_AGENT'])) { - $http_user_agent = 'unknown'; -} else { - $http_user_agent = $_SERVER['HTTP_USER_AGENT']; -} -unset($userinfo); -unset($userid); -unset($customerid); -unset($adminid); -unset($s); - -if (isset($_POST['s'])) { - $s = $_POST['s']; - $nosession = 0; -} elseif (isset($_GET['s'])) { - $s = $_GET['s']; - $nosession = 0; -} else { - $s = ''; - $nosession = 1; +// re-read user data if logged in +if (CurrentUser::hasSession()) { + CurrentUser::reReadUserData(); } -$timediff = time() - Settings::Get('session.sessiontimeout'); -$del_stmt = Database::prepare(" - DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `lastactivity` < :timediff -"); -Database::pexecute($del_stmt, array( - 'timediff' => $timediff -)); - -$userinfo = array(); - -if (isset($s) && $s != "" && $nosession != 1) { - ini_set("session.name", "s"); - ini_set("url_rewriter.tags", ""); - ini_set("session.use_cookies", false); - ini_set("session.cookie_httponly", true); - ini_set("session.cookie_secure", UI::$SSL_REQ); - session_id($s); - session_start(); - $query = "SELECT `s`.*, `u`.* FROM `" . TABLE_PANEL_SESSIONS . "` `s` LEFT JOIN `"; - - if (AREA == 'admin') { - $query .= TABLE_PANEL_ADMINS . "` `u` ON (`s`.`userid` = `u`.`adminid`)"; - $adminsession = '1'; - } else { - $query .= TABLE_PANEL_CUSTOMERS . "` `u` ON (`s`.`userid` = `u`.`customerid`)"; - $adminsession = '0'; - } - - $query .= " WHERE `s`.`hash` = :hash AND `s`.`ipaddress` = :ipaddr - AND `s`.`useragent` = :ua AND `s`.`lastactivity` > :timediff - AND `s`.`adminsession` = :adminsession - "; - - $userinfo_data = array( - 'hash' => $s, - 'ipaddr' => $remote_addr, - 'ua' => $http_user_agent, - 'timediff' => $timediff, - 'adminsession' => $adminsession - ); - $userinfo_stmt = Database::prepare($query); - $userinfo = Database::pexecute_first($userinfo_stmt, $userinfo_data); - - if ($userinfo && (($userinfo['adminsession'] == '1' && AREA == 'admin' && isset($userinfo['adminid'])) || ($userinfo['adminsession'] == '0' && (AREA == 'customer' || AREA == 'login') && isset($userinfo['customerid']))) && (!isset($userinfo['deactivated']) || $userinfo['deactivated'] != '1')) { - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_PANEL_SESSIONS . "` SET - `lastactivity` = :lastactive - WHERE `hash` = :hash AND `adminsession` = :adminsession - "); - $upd_data = array( - 'lastactive' => time(), - 'hash' => $s, - 'adminsession' => $adminsession - ); - Database::pexecute($upd_stmt, $upd_data); - $nosession = 0; - } else { - $nosession = 1; - } -} else { - $nosession = 1; -} - -/** - * Language Management - */ +// Language Management $langs = array(); $languages = array(); $iso = array(); @@ -239,36 +149,31 @@ foreach ($langs as $key => $value) { // ensure that we can display messages $language = Settings::Get('panel.standardlanguage'); -if (isset($userinfo['language']) && isset($languages[$userinfo['language']])) { +if (CurrentUser::hasSession() && !empty(CurrentUser::getField('language')) && isset($languages[CurrentUser::getField('language')])) { // default: use language from session, #277 - $language = $userinfo['language']; + $language = CurrentUser::getField('language'); } else { - if (!isset($userinfo['def_language']) || !isset($languages[$userinfo['def_language']])) // this will always evaluat true, since it is the above statement inverted. @todo remove - { - if (isset($_GET['language']) && isset($languages[$_GET['language']])) { - $language = $_GET['language']; - } else { - if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - $accept_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); - for ($i = 0; $i < count($accept_langs); $i++) { - // this only works for most common languages. some (uncommon) languages have a 3 letter iso-code. - // to be able to use these also, we would have to depend on the intl extension for php (using Locale::lookup or similar) - // as long as froxlor does not support any of these languages, we can leave it like that. - if (isset($iso[substr($accept_langs[$i], 0, 2)])) { - $language = $iso[substr($accept_langs[$i], 0, 2)]; - break; - } + if (!CurrentUser::hasSession()) { + if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + $accept_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); + for ($i = 0; $i < count($accept_langs); $i++) { + // this only works for most common languages. some (uncommon) languages have a 3 letter iso-code. + // to be able to use these also, we would have to depend on the intl extension for php (using Locale::lookup or similar) + // as long as froxlor does not support any of these languages, we can leave it like that. + if (isset($iso[substr($accept_langs[$i], 0, 2)])) { + $language = $iso[substr($accept_langs[$i], 0, 2)]; + break; } - unset($iso); + } + unset($iso); - // if HTTP_ACCEPT_LANGUAGES has no valid langs, use default (very unlikely) - if (!strlen($language) > 0) { - $language = Settings::Get('panel.standardlanguage'); - } + // if HTTP_ACCEPT_LANGUAGES has no valid langs, use default (very unlikely) + if (!strlen($language) > 0) { + $language = Settings::Get('panel.standardlanguage'); } } } else { - $language = $userinfo['def_language']; + $language = CurrentUser::getField('def_language'); } } @@ -290,7 +195,7 @@ include_once \Froxlor\FileDir::makeSecurePath('lng/lng_references.php'); UI::setLng($lng); // Initialize our link - class -$linker = new \Froxlor\UI\Linker('index.php', $s); +$linker = new \Froxlor\UI\Linker('index.php'); UI::setLinker($linker); /** @@ -301,8 +206,8 @@ $theme = (Settings::Get('panel.default_theme') !== null) ? Settings::Get('panel. /** * overwrite with customer/admin theme if defined */ -if (isset($userinfo['theme']) && $userinfo['theme'] != $theme) { - $theme = $userinfo['theme']; +if (CurrentUser::hasSession() && CurrentUser::getField('theme') != $theme) { + $theme = CurrentUser::getField('theme'); } // Check if a different variant of the theme is used @@ -351,8 +256,10 @@ UI::twig()->addGlobal('header_logo', $header_logo); /** * Redirects to index.php (login page) if no session exists */ -if ($nosession == 1 && AREA != 'login') { - unset($userinfo); +if (!CurrentUser::hasSession() && AREA != 'login') { + unset($_SESSION['userinfo']); + CurrentUser::setData(); + session_destroy(); $params = array( "script" => basename($_SERVER["SCRIPT_NAME"]), "qrystr" => $_SERVER["QUERY_STRING"] @@ -361,16 +268,18 @@ if ($nosession == 1 && AREA != 'login') { exit(); } +$userinfo = CurrentUser::getData(); UI::twig()->addGlobal('userinfo', ($userinfo ?? [])); UI::setCurrentUser($userinfo); - -/** - * Logic moved out of lng-file - */ -if (isset($userinfo['loginname']) && $userinfo['loginname'] != '') { - $lng['menue']['main']['username'] .= $userinfo['loginname']; +// Initialize logger +if (CurrentUser::hasSession()) { // Initialize logging $log = \Froxlor\FroxlorLogger::getInstanceOf($userinfo); + if ((CurrentUser::isAdmin() && AREA != 'admin') || (!CurrentUser::isAdmin() && AREA != 'customer')) { + // user tries to access an area not meant for him -> redirect to corresponding index + \Froxlor\UI\Response::redirectTo((CurrentUser::isAdmin() ? 'admin' : 'customer') . '_index.php', $params); + exit(); + } } /** @@ -412,10 +321,10 @@ if (AREA == 'admin' || AREA == 'customer') { ) ) ); - $navigation = \Froxlor\UI\HTML::buildNavigation($navigation_data['admin'], $userinfo); + $navigation = \Froxlor\UI\HTML::buildNavigation($navigation_data['admin'], CurrentUser::getData()); } else { $navigation_data = \Froxlor\PhpHelper::loadConfigArrayDir('lib/navigation/'); - $navigation = \Froxlor\UI\HTML::buildNavigation($navigation_data[AREA], $userinfo); + $navigation = \Froxlor\UI\HTML::buildNavigation($navigation_data[AREA], CurrentUser::getData()); } } UI::twig()->addGlobal('nav_entries', $navigation); @@ -444,34 +353,16 @@ UI::twig()->addGlobal('theme_css', $css); unset($js); unset($css); -/** - * @TODO - * -$panel_imprint_url = Settings::Get('panel.imprint_url'); -if (!empty($panel_imprint_url) && strtolower(substr($panel_imprint_url, 0, 4)) != 'http') { - $panel_imprint_url = 'https://' . $panel_imprint_url; -} -$panel_terms_url = Settings::Get('panel.terms_url'); -if (!empty($panel_terms_url) && strtolower(substr($panel_terms_url, 0, 4)) != 'http') { - $panel_terms_url = 'https://' . $panel_terms_url; -} -$panel_privacy_url = Settings::Get('panel.privacy_url'); -if (!empty($panel_privacy_url) && strtolower(substr($panel_privacy_url, 0, 4)) != 'http') { - $panel_privacy_url = 'https://' . $panel_privacy_url; -} -*/ - $action = Request::get('action'); $page = Request::get('page', 'overview'); // clear request data if (!$action && isset($_SESSION)) { - unset($_SESSION['requestData']); + unset($_SESSION['requestData']); } UI::twig()->addGlobal('action', $action); UI::twig()->addGlobal('page', $page); -UI::twig()->addGlobal('s', $s); /** * Initialize the mailingsystem diff --git a/lib/tablelisting/admin/tablelisting.admins.php b/lib/tablelisting/admin/tablelisting.admins.php index 5e85c2d2..df473110 100644 --- a/lib/tablelisting/admin/tablelisting.admins.php +++ b/lib/tablelisting/admin/tablelisting.admins.php @@ -19,6 +19,7 @@ use Froxlor\UI\Callbacks\ProgressBar; use Froxlor\UI\Callbacks\Style; use Froxlor\UI\Callbacks\Text; +use Froxlor\UI\Callbacks\Impersonate; use Froxlor\UI\Listing; return [ @@ -34,6 +35,7 @@ return [ 'loginname' => [ 'label' => $lng['login']['username'], 'field' => 'loginname', + 'callback' => [Impersonate::class, 'admin'], 'sortable' => true, ], 'name' => [ diff --git a/lib/tablelisting/admin/tablelisting.customers.php b/lib/tablelisting/admin/tablelisting.customers.php index 377a42ce..bbebae58 100644 --- a/lib/tablelisting/admin/tablelisting.customers.php +++ b/lib/tablelisting/admin/tablelisting.customers.php @@ -40,7 +40,7 @@ return [ ], 'a.loginname' => [ 'label' => $lng['admin']['admin'], - 'field' => 'admin.loginname', + 'field' => 'adminname', 'callback' => [Impersonate::class, 'admin'], ], 'c.email' => [ diff --git a/lib/tables.inc.php b/lib/tables.inc.php index 3c819da5..13c0d2d9 100644 --- a/lib/tables.inc.php +++ b/lib/tables.inc.php @@ -31,7 +31,6 @@ const TABLE_PANEL_DATABASES = 'panel_databases'; const TABLE_PANEL_DOMAINS = 'panel_domains'; const TABLE_PANEL_HTACCESS = 'panel_htaccess'; const TABLE_PANEL_HTPASSWDS = 'panel_htpasswds'; -const TABLE_PANEL_SESSIONS = 'panel_sessions'; const TABLE_PANEL_SETTINGS = 'panel_settings'; const TABLE_PANEL_TASKS = 'panel_tasks'; const TABLE_PANEL_TEMPLATES = 'panel_templates'; diff --git a/lng/english.lng.php b/lng/english.lng.php index e239efc3..8fc13ae3 100644 --- a/lng/english.lng.php +++ b/lng/english.lng.php @@ -1554,7 +1554,6 @@ $lng['serversettings']['phpfpm_settings']['idle_timeout']['description'] = 'Time // ADDED IN 0.9.27-svn2 $lng['panel']['cancel'] = 'Cancel'; -$lng['admin']['delete_statistics'] = 'Delete Statistics'; $lng['admin']['speciallogwarning'] = '
WARNING: By changing this setting you will lose all your old statistics for this domain.
'; // ADDED IN 0.9.28-svn2 diff --git a/logfiles_viewer.php b/logfiles_viewer.php index a0e8be0c..0d54a47d 100644 --- a/logfiles_viewer.php +++ b/logfiles_viewer.php @@ -34,8 +34,7 @@ $last_n = (int) Request::get('number_of_lines', 100); if (AREA != 'admin' && $userinfo['logviewenabled'] != '1') { // back to domain overview \Froxlor\UI\Response::redirectTo($filename, array( - 'page' => 'domains', - 's' => $s + 'page' => 'domains' )); } diff --git a/templates/Froxlor/assets/js/main.js b/templates/Froxlor/assets/js/main.js index 6b7615e3..3df40585 100644 --- a/templates/Froxlor/assets/js/main.js +++ b/templates/Froxlor/assets/js/main.js @@ -1,2 +1,2 @@ /*! For license information please see main.js.LICENSE.txt */ -(()=>{var e,t={444:()=>{$(document).ready((function(){$("input[name$='_ul']").each((function(){var e=$(this).attr("name").substring(0,$(this).attr("name").length-3);$("input[name='"+e+"']").prop({readonly:$(this).is(":checked"),required:!$(this).is(":checked")})})),$("input[name$='_ul']").change((function(){var e=$(this).attr("name").substring(0,$(this).attr("name").length-3);$("input[name='"+e+"']").prop({readonly:$(this).is(":checked"),required:!$(this).is(":checked")}),$(this).is(":checked")||$("input[name='"+e+"']").focus()})),$("#use_plan").change((function(){var e=$(this).val();e>0&&$.ajax({url:"admin_plans.php?s="+window.$session+"&page=overview&action=jqGetPlanValues",type:"POST",data:{planid:e},dataType:"json",success:function(e){for(var t in e)"email_imap"==t||"email_pop3"==t||"perlenabled"==t||"phpenabled"==t||"dnsenabled"==t||"logviewenabled"==t?1==e[t]?$("input[name='"+t+"']").prop("checked",!0):$("input[name='"+t+"']").prop("checked",!1):"allowed_phpconfigs"==t?$("input[name='allowed_phpconfigs[]']").each((function(n){for(var i in $(this).prop("checked",!1),e[t])if($(this).val()==e[t][i]){$(this).prop("checked",!0);break}})):-1==e[t]?($("input[name='"+t+"_ul']").attr("checked","checked"),$("input[name='"+t+"']").prop({readonly:!0})):($("input[name='"+t+"']").val(e[t]),$("input[name='"+t+"']").prop({readonly:!1}),$("input[name='"+t+"_ul']").prop("checked",!1))},error:function(e,t){console.log(e,t)}})}))}))},960:()=>{$(document).ready((function(){$("#customerid").change((function(){var e=$(this).val();$.ajax({url:"admin_domains.php?s="+window.$session+"&page=domains&action=jqGetCustomerPHPConfigs",type:"POST",data:{customerid:e},dataType:"json",success:function(e){e.length>0&&$("#phpsettingid option").each((function(){var t=$(this).val();for(var n in $(this).attr("disabled","disabled"),e)t==e[n]&&$(this).removeAttr("disabled")}))},error:function(e,t){console.log(e,t)}})})),$("input[name=speciallogverified]")&&$("input[name=speciallogfile]").click((function(){$("#speciallogfilenote").remove(),$("#speciallogfile").removeClass("is-invalid"),$("#speciallogverified").val(0),$.ajax({url:"admin_domains.php?s="+window.$session+"&page=overview&action=jqSpeciallogfileNote",type:"POST",data:{id:$("input[name=id]").val(),newval:+$("#speciallogfile").is(":checked")},dataType:"json",success:function(e){e.changed&&($("#speciallogfile").addClass("is-invalid"),$("#speciallogfile").parent().append(e.info),$("#speciallogverified").val(1))},error:function(e,t){console.log(e,t)}})}))}))},786:()=>{$(document).ready((function(){$("#ip").change((function(){var e=$(this).val();e.length>0&&($("#ipnote").remove(),$("#ip").removeClass("is-invalid"),$.ajax({url:"admin_ipsandports.php?s="+window.$session+"&page=overview&action=jqCheckIP",type:"POST",data:{ip:e},dataType:"json",success:function(e){0!=e&&($("#ip").addClass("is-invalid"),$("#ip").parent().append(e))},error:function(e,t){console.log(e,t)}}))}))}))},470:()=>{$(document).ready((function(){if(document.getElementById("newsfeed")){var e="";void 0!==$("#newsfeed").data("role")&&(e="&role="+$("#newsfeed").data("role")),$.ajax({url:"lib/ajax.php?action=newsfeed"+e+"&theme="+window.$theme+"&s="+window.$session,type:"GET",success:function(e){$("#newsfeeditems").html(e)},error:function(e,t,n){console.log(e,t,n),$("#newsfeeditems").html('')}})}}))},511:()=>{$(document).ready((function(){var e=$("#search");e.submit((function(e){e.preventDefault()})),e.find("input").on("keyup",(function(){var e=$(this).val(),t=$("#search-dropdown");e.length?e.length&&e.length<3?t.show().html('
  • Please enter more than 2 characters
  • '):$.ajax({url:"lib/ajax.php?action=searchglobal&theme="+window.$theme+"&s="+window.$session,type:"POST",data:{searchtext:e},dataType:"json",success:function(e){0!==Object.keys(e).length?(t.show().html(""),Object.keys(e).forEach((function(n){t.append('
  • '+n+"
  • "),e[n].forEach((function(e){t.append('
  • '+e.title+"
  • ")}))}))):t.show().html('
  • Nothing found!
  • ')},error:function(e,n){console.log(e,n),t.show().html('
  • Whoops we got some errors!
  • ')}}):t.hide().html("")}))}))},414:()=>{$(document).ready((function(){document.getElementById("updatecheck")&&$.ajax({url:"lib/ajax.php?action=updatecheck&theme="+window.$theme+"&s="+window.$session,type:"GET",success:function(e){$("#updatecheck").html(e)},error:function(e,t,n){console.log(e,t,n);var i="Can't check version";$("#updatecheck").html(' '+i+"")}})}))},506:(e,t,n)=>{"use strict";var i={};n.r(i),n.d(i,{afterMain:()=>E,afterRead:()=>_,afterWrite:()=>A,applyStyles:()=>j,arrow:()=>J,auto:()=>l,basePlacements:()=>c,beforeMain:()=>w,beforeRead:()=>y,beforeWrite:()=>T,bottom:()=>o,clippingParents:()=>f,computeStyles:()=>ne,createPopper:()=>Le,createPopperBase:()=>Ne,createPopperLite:()=>je,detectOverflow:()=>ye,end:()=>d,eventListeners:()=>re,flip:()=>be,hide:()=>xe,left:()=>a,main:()=>x,modifierPhases:()=>k,offset:()=>Ee,placements:()=>v,popper:()=>p,popperGenerator:()=>De,popperOffsets:()=>Te,preventOverflow:()=>Ce,read:()=>b,reference:()=>g,right:()=>s,start:()=>u,top:()=>r,variationPlacements:()=>m,viewport:()=>h,write:()=>C});var r="top",o="bottom",s="right",a="left",l="auto",c=[r,o,s,a],u="start",d="end",f="clippingParents",h="viewport",p="popper",g="reference",m=c.reduce((function(e,t){return e.concat([t+"-"+u,t+"-"+d])}),[]),v=[].concat(c,[l]).reduce((function(e,t){return e.concat([t,t+"-"+u,t+"-"+d])}),[]),y="beforeRead",b="read",_="afterRead",w="beforeMain",x="main",E="afterMain",T="beforeWrite",C="write",A="afterWrite",k=[y,b,_,w,x,E,T,C,A];function S(e){return e?(e.nodeName||"").toLowerCase():null}function O(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function D(e){return e instanceof O(e).Element||e instanceof Element}function N(e){return e instanceof O(e).HTMLElement||e instanceof HTMLElement}function L(e){return"undefined"!=typeof ShadowRoot&&(e instanceof O(e).ShadowRoot||e instanceof ShadowRoot)}const j={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},i=t.attributes[e]||{},r=t.elements[e];N(r)&&S(r)&&(Object.assign(r.style,n),Object.keys(i).forEach((function(e){var t=i[e];!1===t?r.removeAttribute(e):r.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var i=t.elements[e],r=t.attributes[e]||{},o=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});N(i)&&S(i)&&(Object.assign(i.style,o),Object.keys(r).forEach((function(e){i.removeAttribute(e)})))}))}},requires:["computeStyles"]};function P(e){return e.split("-")[0]}var I=Math.max,H=Math.min,q=Math.round;function M(e,t){void 0===t&&(t=!1);var n=e.getBoundingClientRect(),i=1,r=1;if(N(e)&&t){var o=e.offsetHeight,s=e.offsetWidth;s>0&&(i=q(n.width)/s||1),o>0&&(r=q(n.height)/o||1)}return{width:n.width/i,height:n.height/r,top:n.top/r,right:n.right/i,bottom:n.bottom/r,left:n.left/i,x:n.left/i,y:n.top/r}}function R(e){var t=M(e),n=e.offsetWidth,i=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-i)<=1&&(i=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:i}}function B(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&L(n)){var i=t;do{if(i&&e.isSameNode(i))return!0;i=i.parentNode||i.host}while(i)}return!1}function W(e){return O(e).getComputedStyle(e)}function F(e){return["table","td","th"].indexOf(S(e))>=0}function z(e){return((D(e)?e.ownerDocument:e.document)||window.document).documentElement}function U(e){return"html"===S(e)?e:e.assignedSlot||e.parentNode||(L(e)?e.host:null)||z(e)}function V(e){return N(e)&&"fixed"!==W(e).position?e.offsetParent:null}function X(e){for(var t=O(e),n=V(e);n&&F(n)&&"static"===W(n).position;)n=V(n);return n&&("html"===S(n)||"body"===S(n)&&"static"===W(n).position)?t:n||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&N(e)&&"fixed"===W(e).position)return null;for(var n=U(e);N(n)&&["html","body"].indexOf(S(n))<0;){var i=W(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||t}function Y(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function K(e,t,n){return I(e,H(t,n))}function Q(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function G(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}const J={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,i=e.name,l=e.options,u=n.elements.arrow,d=n.modifiersData.popperOffsets,f=P(n.placement),h=Y(f),p=[a,s].indexOf(f)>=0?"height":"width";if(u&&d){var g=function(e,t){return Q("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:G(e,c))}(l.padding,n),m=R(u),v="y"===h?r:a,y="y"===h?o:s,b=n.rects.reference[p]+n.rects.reference[h]-d[h]-n.rects.popper[p],_=d[h]-n.rects.reference[h],w=X(u),x=w?"y"===h?w.clientHeight||0:w.clientWidth||0:0,E=b/2-_/2,T=g[v],C=x-m[p]-g[y],A=x/2-m[p]/2+E,k=K(T,A,C),S=h;n.modifiersData[i]=((t={})[S]=k,t.centerOffset=k-A,t)}},effect:function(e){var t=e.state,n=e.options.element,i=void 0===n?"[data-popper-arrow]":n;null!=i&&("string"!=typeof i||(i=t.elements.popper.querySelector(i)))&&B(t.elements.popper,i)&&(t.elements.arrow=i)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Z(e){return e.split("-")[1]}var ee={top:"auto",right:"auto",bottom:"auto",left:"auto"};function te(e){var t,n=e.popper,i=e.popperRect,l=e.placement,c=e.variation,u=e.offsets,f=e.position,h=e.gpuAcceleration,p=e.adaptive,g=e.roundOffsets,m=e.isFixed,v=u.x,y=void 0===v?0:v,b=u.y,_=void 0===b?0:b,w="function"==typeof g?g({x:y,y:_}):{x:y,y:_};y=w.x,_=w.y;var x=u.hasOwnProperty("x"),E=u.hasOwnProperty("y"),T=a,C=r,A=window;if(p){var k=X(n),S="clientHeight",D="clientWidth";if(k===O(n)&&"static"!==W(k=z(n)).position&&"absolute"===f&&(S="scrollHeight",D="scrollWidth"),k=k,l===r||(l===a||l===s)&&c===d)C=o,_-=(m&&A.visualViewport?A.visualViewport.height:k[S])-i.height,_*=h?1:-1;if(l===a||(l===r||l===o)&&c===d)T=s,y-=(m&&A.visualViewport?A.visualViewport.width:k[D])-i.width,y*=h?1:-1}var N,L=Object.assign({position:f},p&&ee),j=!0===g?function(e){var t=e.x,n=e.y,i=window.devicePixelRatio||1;return{x:q(t*i)/i||0,y:q(n*i)/i||0}}({x:y,y:_}):{x:y,y:_};return y=j.x,_=j.y,h?Object.assign({},L,((N={})[C]=E?"0":"",N[T]=x?"0":"",N.transform=(A.devicePixelRatio||1)<=1?"translate("+y+"px, "+_+"px)":"translate3d("+y+"px, "+_+"px, 0)",N)):Object.assign({},L,((t={})[C]=E?_+"px":"",t[T]=x?y+"px":"",t.transform="",t))}const ne={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,i=n.gpuAcceleration,r=void 0===i||i,o=n.adaptive,s=void 0===o||o,a=n.roundOffsets,l=void 0===a||a,c={placement:P(t.placement),variation:Z(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:r,isFixed:"fixed"===t.options.strategy};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,te(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:s,roundOffsets:l})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,te(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}};var ie={passive:!0};const re={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var t=e.state,n=e.instance,i=e.options,r=i.scroll,o=void 0===r||r,s=i.resize,a=void 0===s||s,l=O(t.elements.popper),c=[].concat(t.scrollParents.reference,t.scrollParents.popper);return o&&c.forEach((function(e){e.addEventListener("scroll",n.update,ie)})),a&&l.addEventListener("resize",n.update,ie),function(){o&&c.forEach((function(e){e.removeEventListener("scroll",n.update,ie)})),a&&l.removeEventListener("resize",n.update,ie)}},data:{}};var oe={left:"right",right:"left",bottom:"top",top:"bottom"};function se(e){return e.replace(/left|right|bottom|top/g,(function(e){return oe[e]}))}var ae={start:"end",end:"start"};function le(e){return e.replace(/start|end/g,(function(e){return ae[e]}))}function ce(e){var t=O(e);return{scrollLeft:t.pageXOffset,scrollTop:t.pageYOffset}}function ue(e){return M(z(e)).left+ce(e).scrollLeft}function de(e){var t=W(e),n=t.overflow,i=t.overflowX,r=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+r+i)}function fe(e){return["html","body","#document"].indexOf(S(e))>=0?e.ownerDocument.body:N(e)&&de(e)?e:fe(U(e))}function he(e,t){var n;void 0===t&&(t=[]);var i=fe(e),r=i===(null==(n=e.ownerDocument)?void 0:n.body),o=O(i),s=r?[o].concat(o.visualViewport||[],de(i)?i:[]):i,a=t.concat(s);return r?a:a.concat(he(U(s)))}function pe(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function ge(e,t){return t===h?pe(function(e){var t=O(e),n=z(e),i=t.visualViewport,r=n.clientWidth,o=n.clientHeight,s=0,a=0;return i&&(r=i.width,o=i.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=i.offsetLeft,a=i.offsetTop)),{width:r,height:o,x:s+ue(e),y:a}}(e)):D(t)?function(e){var t=M(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(t):pe(function(e){var t,n=z(e),i=ce(e),r=null==(t=e.ownerDocument)?void 0:t.body,o=I(n.scrollWidth,n.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),s=I(n.scrollHeight,n.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),a=-i.scrollLeft+ue(e),l=-i.scrollTop;return"rtl"===W(r||n).direction&&(a+=I(n.clientWidth,r?r.clientWidth:0)-o),{width:o,height:s,x:a,y:l}}(z(e)))}function me(e,t,n){var i="clippingParents"===t?function(e){var t=he(U(e)),n=["absolute","fixed"].indexOf(W(e).position)>=0&&N(e)?X(e):e;return D(n)?t.filter((function(e){return D(e)&&B(e,n)&&"body"!==S(e)})):[]}(e):[].concat(t),r=[].concat(i,[n]),o=r[0],s=r.reduce((function(t,n){var i=ge(e,n);return t.top=I(i.top,t.top),t.right=H(i.right,t.right),t.bottom=H(i.bottom,t.bottom),t.left=I(i.left,t.left),t}),ge(e,o));return s.width=s.right-s.left,s.height=s.bottom-s.top,s.x=s.left,s.y=s.top,s}function ve(e){var t,n=e.reference,i=e.element,l=e.placement,c=l?P(l):null,f=l?Z(l):null,h=n.x+n.width/2-i.width/2,p=n.y+n.height/2-i.height/2;switch(c){case r:t={x:h,y:n.y-i.height};break;case o:t={x:h,y:n.y+n.height};break;case s:t={x:n.x+n.width,y:p};break;case a:t={x:n.x-i.width,y:p};break;default:t={x:n.x,y:n.y}}var g=c?Y(c):null;if(null!=g){var m="y"===g?"height":"width";switch(f){case u:t[g]=t[g]-(n[m]/2-i[m]/2);break;case d:t[g]=t[g]+(n[m]/2-i[m]/2)}}return t}function ye(e,t){void 0===t&&(t={});var n=t,i=n.placement,a=void 0===i?e.placement:i,l=n.boundary,u=void 0===l?f:l,d=n.rootBoundary,m=void 0===d?h:d,v=n.elementContext,y=void 0===v?p:v,b=n.altBoundary,_=void 0!==b&&b,w=n.padding,x=void 0===w?0:w,E=Q("number"!=typeof x?x:G(x,c)),T=y===p?g:p,C=e.rects.popper,A=e.elements[_?T:y],k=me(D(A)?A:A.contextElement||z(e.elements.popper),u,m),S=M(e.elements.reference),O=ve({reference:S,element:C,strategy:"absolute",placement:a}),N=pe(Object.assign({},C,O)),L=y===p?N:S,j={top:k.top-L.top+E.top,bottom:L.bottom-k.bottom+E.bottom,left:k.left-L.left+E.left,right:L.right-k.right+E.right},P=e.modifiersData.offset;if(y===p&&P){var I=P[a];Object.keys(j).forEach((function(e){var t=[s,o].indexOf(e)>=0?1:-1,n=[r,o].indexOf(e)>=0?"y":"x";j[e]+=I[n]*t}))}return j}const be={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,i=e.name;if(!t.modifiersData[i]._skip){for(var d=n.mainAxis,f=void 0===d||d,h=n.altAxis,p=void 0===h||h,g=n.fallbackPlacements,y=n.padding,b=n.boundary,_=n.rootBoundary,w=n.altBoundary,x=n.flipVariations,E=void 0===x||x,T=n.allowedAutoPlacements,C=t.options.placement,A=P(C),k=g||(A===C||!E?[se(C)]:function(e){if(P(e)===l)return[];var t=se(e);return[le(e),t,le(t)]}(C)),S=[C].concat(k).reduce((function(e,n){return e.concat(P(n)===l?function(e,t){void 0===t&&(t={});var n=t,i=n.placement,r=n.boundary,o=n.rootBoundary,s=n.padding,a=n.flipVariations,l=n.allowedAutoPlacements,u=void 0===l?v:l,d=Z(i),f=d?a?m:m.filter((function(e){return Z(e)===d})):c,h=f.filter((function(e){return u.indexOf(e)>=0}));0===h.length&&(h=f);var p=h.reduce((function(t,n){return t[n]=ye(e,{placement:n,boundary:r,rootBoundary:o,padding:s})[P(n)],t}),{});return Object.keys(p).sort((function(e,t){return p[e]-p[t]}))}(t,{placement:n,boundary:b,rootBoundary:_,padding:y,flipVariations:E,allowedAutoPlacements:T}):n)}),[]),O=t.rects.reference,D=t.rects.popper,N=new Map,L=!0,j=S[0],I=0;I=0,R=M?"width":"height",B=ye(t,{placement:$,boundary:b,rootBoundary:_,altBoundary:w,padding:y}),W=M?q?s:a:q?o:r;O[R]>D[R]&&(W=se(W));var F=se(W),z=[];if(f&&z.push(B[H]<=0),p&&z.push(B[W]<=0,B[F]<=0),z.every((function(e){return e}))){j=$,L=!1;break}N.set($,z)}if(L)for(var U=function(e){var t=S.find((function(t){var n=N.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return j=t,"break"},V=E?3:1;V>0;V--){if("break"===U(V))break}t.placement!==j&&(t.modifiersData[i]._skip=!0,t.placement=j,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function _e(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function we(e){return[r,s,o,a].some((function(t){return e[t]>=0}))}const xe={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,i=t.rects.reference,r=t.rects.popper,o=t.modifiersData.preventOverflow,s=ye(t,{elementContext:"reference"}),a=ye(t,{altBoundary:!0}),l=_e(s,i),c=_e(a,r,o),u=we(l),d=we(c);t.modifiersData[n]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:u,hasPopperEscaped:d},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":u,"data-popper-escaped":d})}};const Ee={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,i=e.name,o=n.offset,l=void 0===o?[0,0]:o,c=v.reduce((function(e,n){return e[n]=function(e,t,n){var i=P(e),o=[a,r].indexOf(i)>=0?-1:1,l="function"==typeof n?n(Object.assign({},t,{placement:e})):n,c=l[0],u=l[1];return c=c||0,u=(u||0)*o,[a,s].indexOf(i)>=0?{x:u,y:c}:{x:c,y:u}}(n,t.rects,l),e}),{}),u=c[t.placement],d=u.x,f=u.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=d,t.modifiersData.popperOffsets.y+=f),t.modifiersData[i]=c}};const Te={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=ve({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}};const Ce={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,i=e.name,l=n.mainAxis,c=void 0===l||l,d=n.altAxis,f=void 0!==d&&d,h=n.boundary,p=n.rootBoundary,g=n.altBoundary,m=n.padding,v=n.tether,y=void 0===v||v,b=n.tetherOffset,_=void 0===b?0:b,w=ye(t,{boundary:h,rootBoundary:p,padding:m,altBoundary:g}),x=P(t.placement),E=Z(t.placement),T=!E,C=Y(x),A="x"===C?"y":"x",k=t.modifiersData.popperOffsets,S=t.rects.reference,O=t.rects.popper,D="function"==typeof _?_(Object.assign({},t.rects,{placement:t.placement})):_,N="number"==typeof D?{mainAxis:D,altAxis:D}:Object.assign({mainAxis:0,altAxis:0},D),L=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,j={x:0,y:0};if(k){if(c){var $,q="y"===C?r:a,M="y"===C?o:s,B="y"===C?"height":"width",W=k[C],F=W+w[q],z=W-w[M],U=y?-O[B]/2:0,V=E===u?S[B]:O[B],Q=E===u?-O[B]:-S[B],G=t.elements.arrow,J=y&&G?R(G):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[q],ne=ee[M],ie=K(0,S[B],J[B]),re=T?S[B]/2-U-ie-te-N.mainAxis:V-ie-te-N.mainAxis,oe=T?-S[B]/2+U+ie+ne+N.mainAxis:Q+ie+ne+N.mainAxis,se=t.elements.arrow&&X(t.elements.arrow),ae=se?"y"===C?se.clientTop||0:se.clientLeft||0:0,le=null!=($=null==L?void 0:L[C])?$:0,ce=W+oe-le,ue=K(y?H(F,W+re-le-ae):F,W,y?I(z,ce):z);k[C]=ue,j[C]=ue-W}if(f){var de,fe="x"===C?r:a,he="x"===C?o:s,pe=k[A],ge="y"===A?"height":"width",me=pe+w[fe],ve=pe-w[he],be=-1!==[r,a].indexOf(x),_e=null!=(de=null==L?void 0:L[A])?de:0,we=be?me:pe-S[ge]-O[ge]-_e+N.altAxis,xe=be?pe+S[ge]+O[ge]-_e-N.altAxis:ve,Ee=y&&be?function(e,t,n){var i=K(e,t,n);return i>n?n:i}(we,pe,xe):K(y?we:me,pe,y?xe:ve);k[A]=Ee,j[A]=Ee-pe}t.modifiersData[i]=j}},requiresIfExists:["offset"]};function Ae(e,t,n){void 0===n&&(n=!1);var i,r,o=N(t),s=N(t)&&function(e){var t=e.getBoundingClientRect(),n=q(t.width)/e.offsetWidth||1,i=q(t.height)/e.offsetHeight||1;return 1!==n||1!==i}(t),a=z(t),l=M(e,s),c={scrollLeft:0,scrollTop:0},u={x:0,y:0};return(o||!o&&!n)&&(("body"!==S(t)||de(a))&&(c=(i=t)!==O(i)&&N(i)?{scrollLeft:(r=i).scrollLeft,scrollTop:r.scrollTop}:ce(i)),N(t)?((u=M(t,!0)).x+=t.clientLeft,u.y+=t.clientTop):a&&(u.x=ue(a))),{x:l.left+c.scrollLeft-u.x,y:l.top+c.scrollTop-u.y,width:l.width,height:l.height}}function ke(e){var t=new Map,n=new Set,i=[];function r(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var i=t.get(e);i&&r(i)}})),i.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||r(e)})),i}var Se={placement:"bottom",modifiers:[],strategy:"absolute"};function Oe(){for(var e=arguments.length,t=new Array(e),n=0;n{let t=e.getAttribute("data-bs-target");if(!t||"#"===t){let n=e.getAttribute("href");if(!n||!n.includes("#")&&!n.startsWith("."))return null;n.includes("#")&&!n.startsWith("#")&&(n=`#${n.split("#")[1]}`),t=n&&"#"!==n?n.trim():null}return t},$e=e=>{const t=Ie(e);return t&&document.querySelector(t)?t:null},He=e=>{const t=Ie(e);return t?document.querySelector(t):null},qe=e=>{e.dispatchEvent(new Event(Pe))},Me=e=>!(!e||"object"!=typeof e)&&(void 0!==e.jquery&&(e=e[0]),void 0!==e.nodeType),Re=e=>Me(e)?e.jquery?e[0]:e:"string"==typeof e&&e.length>0?document.querySelector(e):null,Be=(e,t,n)=>{Object.keys(n).forEach((i=>{const r=n[i],o=t[i],s=o&&Me(o)?"element":null==(a=o)?`${a}`:{}.toString.call(a).match(/\s([a-z]+)/i)[1].toLowerCase();var a;if(!new RegExp(r).test(s))throw new TypeError(`${e.toUpperCase()}: Option "${i}" provided type "${s}" but expected type "${r}".`)}))},We=e=>!(!Me(e)||0===e.getClientRects().length)&&"visible"===getComputedStyle(e).getPropertyValue("visibility"),Fe=e=>!e||e.nodeType!==Node.ELEMENT_NODE||(!!e.classList.contains("disabled")||(void 0!==e.disabled?e.disabled:e.hasAttribute("disabled")&&"false"!==e.getAttribute("disabled"))),ze=e=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){const t=e.getRootNode();return t instanceof ShadowRoot?t:null}return e instanceof ShadowRoot?e:e.parentNode?ze(e.parentNode):null},Ue=()=>{},Ve=e=>{e.offsetHeight},Xe=()=>{const{jQuery:e}=window;return e&&!document.body.hasAttribute("data-bs-no-jquery")?e:null},Ye=[],Ke=()=>"rtl"===document.documentElement.dir,Qe=e=>{var t;t=()=>{const t=Xe();if(t){const n=e.NAME,i=t.fn[n];t.fn[n]=e.jQueryInterface,t.fn[n].Constructor=e,t.fn[n].noConflict=()=>(t.fn[n]=i,e.jQueryInterface)}},"loading"===document.readyState?(Ye.length||document.addEventListener("DOMContentLoaded",(()=>{Ye.forEach((e=>e()))})),Ye.push(t)):t()},Ge=e=>{"function"==typeof e&&e()},Je=(e,t,n=!0)=>{if(!n)return void Ge(e);const i=(e=>{if(!e)return 0;let{transitionDuration:t,transitionDelay:n}=window.getComputedStyle(e);const i=Number.parseFloat(t),r=Number.parseFloat(n);return i||r?(t=t.split(",")[0],n=n.split(",")[0],1e3*(Number.parseFloat(t)+Number.parseFloat(n))):0})(t)+5;let r=!1;const o=({target:n})=>{n===t&&(r=!0,t.removeEventListener(Pe,o),Ge(e))};t.addEventListener(Pe,o),setTimeout((()=>{r||qe(t)}),i)},Ze=(e,t,n,i)=>{let r=e.indexOf(t);if(-1===r)return e[!n&&i?e.length-1:0];const o=e.length;return r+=n?1:-1,i&&(r=(r+o)%o),e[Math.max(0,Math.min(r,o-1))]},et=/[^.]*(?=\..*)\.|.*/,tt=/\..*/,nt=/::\d+$/,it={};let rt=1;const ot={mouseenter:"mouseover",mouseleave:"mouseout"},st=/^(mouseenter|mouseleave)/i,at=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function lt(e,t){return t&&`${t}::${rt++}`||e.uidEvent||rt++}function ct(e){const t=lt(e);return e.uidEvent=t,it[t]=it[t]||{},it[t]}function ut(e,t,n=null){const i=Object.keys(e);for(let r=0,o=i.length;rfunction(t){if(!t.relatedTarget||t.relatedTarget!==t.delegateTarget&&!t.delegateTarget.contains(t.relatedTarget))return e.call(this,t)};i?i=e(i):n=e(n)}const[o,s,a]=dt(t,n,i),l=ct(e),c=l[a]||(l[a]={}),u=ut(c,s,o?n:null);if(u)return void(u.oneOff=u.oneOff&&r);const d=lt(s,t.replace(et,"")),f=o?function(e,t,n){return function i(r){const o=e.querySelectorAll(t);for(let{target:s}=r;s&&s!==this;s=s.parentNode)for(let a=o.length;a--;)if(o[a]===s)return r.delegateTarget=s,i.oneOff&>.off(e,r.type,t,n),n.apply(s,[r]);return null}}(e,n,i):function(e,t){return function n(i){return i.delegateTarget=e,n.oneOff&>.off(e,i.type,t),t.apply(e,[i])}}(e,n);f.delegationSelector=o?n:null,f.originalHandler=s,f.oneOff=r,f.uidEvent=d,c[d]=f,e.addEventListener(a,f,o)}function ht(e,t,n,i,r){const o=ut(t[n],i,r);o&&(e.removeEventListener(n,o,Boolean(r)),delete t[n][o.uidEvent])}function pt(e){return e=e.replace(tt,""),ot[e]||e}const gt={on(e,t,n,i){ft(e,t,n,i,!1)},one(e,t,n,i){ft(e,t,n,i,!0)},off(e,t,n,i){if("string"!=typeof t||!e)return;const[r,o,s]=dt(t,n,i),a=s!==t,l=ct(e),c=t.startsWith(".");if(void 0!==o){if(!l||!l[s])return;return void ht(e,l,s,o,r?n:null)}c&&Object.keys(l).forEach((n=>{!function(e,t,n,i){const r=t[n]||{};Object.keys(r).forEach((o=>{if(o.includes(i)){const i=r[o];ht(e,t,n,i.originalHandler,i.delegationSelector)}}))}(e,l,n,t.slice(1))}));const u=l[s]||{};Object.keys(u).forEach((n=>{const i=n.replace(nt,"");if(!a||t.includes(i)){const t=u[n];ht(e,l,s,t.originalHandler,t.delegationSelector)}}))},trigger(e,t,n){if("string"!=typeof t||!e)return null;const i=Xe(),r=pt(t),o=t!==r,s=at.has(r);let a,l=!0,c=!0,u=!1,d=null;return o&&i&&(a=i.Event(t,n),i(e).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),u=a.isDefaultPrevented()),s?(d=document.createEvent("HTMLEvents"),d.initEvent(r,l,!0)):d=new CustomEvent(t,{bubbles:l,cancelable:!0}),void 0!==n&&Object.keys(n).forEach((e=>{Object.defineProperty(d,e,{get:()=>n[e]})})),u&&d.preventDefault(),c&&e.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},mt=new Map,vt={set(e,t,n){mt.has(e)||mt.set(e,new Map);const i=mt.get(e);i.has(t)||0===i.size?i.set(t,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(i.keys())[0]}.`)},get:(e,t)=>mt.has(e)&&mt.get(e).get(t)||null,remove(e,t){if(!mt.has(e))return;const n=mt.get(e);n.delete(t),0===n.size&&mt.delete(e)}};class yt{constructor(e){(e=Re(e))&&(this._element=e,vt.set(this._element,this.constructor.DATA_KEY,this))}dispose(){vt.remove(this._element,this.constructor.DATA_KEY),gt.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach((e=>{this[e]=null}))}_queueCallback(e,t,n=!0){Je(e,t,n)}static getInstance(e){return vt.get(Re(e),this.DATA_KEY)}static getOrCreateInstance(e,t={}){return this.getInstance(e)||new this(e,"object"==typeof t?t:null)}static get VERSION(){return"5.1.3"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}}const bt=(e,t="hide")=>{const n=`click.dismiss${e.EVENT_KEY}`,i=e.NAME;gt.on(document,n,`[data-bs-dismiss="${i}"]`,(function(n){if(["A","AREA"].includes(this.tagName)&&n.preventDefault(),Fe(this))return;const r=He(this)||this.closest(`.${i}`);e.getOrCreateInstance(r)[t]()}))};class _t extends yt{static get NAME(){return"alert"}close(){if(gt.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const e=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,e)}_destroyElement(){this._element.remove(),gt.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(e){return this.each((function(){const t=_t.getOrCreateInstance(this);if("string"==typeof e){if(void 0===t[e]||e.startsWith("_")||"constructor"===e)throw new TypeError(`No method named "${e}"`);t[e](this)}}))}}bt(_t,"close"),Qe(_t);const wt='[data-bs-toggle="button"]';class xt extends yt{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(e){return this.each((function(){const t=xt.getOrCreateInstance(this);"toggle"===e&&t[e]()}))}}function Et(e){return"true"===e||"false"!==e&&(e===Number(e).toString()?Number(e):""===e||"null"===e?null:e)}function Tt(e){return e.replace(/[A-Z]/g,(e=>`-${e.toLowerCase()}`))}gt.on(document,"click.bs.button.data-api",wt,(e=>{e.preventDefault();const t=e.target.closest(wt);xt.getOrCreateInstance(t).toggle()})),Qe(xt);const Ct={setDataAttribute(e,t,n){e.setAttribute(`data-bs-${Tt(t)}`,n)},removeDataAttribute(e,t){e.removeAttribute(`data-bs-${Tt(t)}`)},getDataAttributes(e){if(!e)return{};const t={};return Object.keys(e.dataset).filter((e=>e.startsWith("bs"))).forEach((n=>{let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),t[i]=Et(e.dataset[n])})),t},getDataAttribute:(e,t)=>Et(e.getAttribute(`data-bs-${Tt(t)}`)),offset(e){const t=e.getBoundingClientRect();return{top:t.top+window.pageYOffset,left:t.left+window.pageXOffset}},position:e=>({top:e.offsetTop,left:e.offsetLeft})},At={find:(e,t=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(t,e)),findOne:(e,t=document.documentElement)=>Element.prototype.querySelector.call(t,e),children:(e,t)=>[].concat(...e.children).filter((e=>e.matches(t))),parents(e,t){const n=[];let i=e.parentNode;for(;i&&i.nodeType===Node.ELEMENT_NODE&&3!==i.nodeType;)i.matches(t)&&n.push(i),i=i.parentNode;return n},prev(e,t){let n=e.previousElementSibling;for(;n;){if(n.matches(t))return[n];n=n.previousElementSibling}return[]},next(e,t){let n=e.nextElementSibling;for(;n;){if(n.matches(t))return[n];n=n.nextElementSibling}return[]},focusableChildren(e){const t=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((e=>`${e}:not([tabindex^="-"])`)).join(", ");return this.find(t,e).filter((e=>!Fe(e)&&We(e)))}},kt="carousel",St={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Ot={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},Dt="next",Nt="prev",Lt="left",jt="right",Pt={ArrowLeft:jt,ArrowRight:Lt},It="slid.bs.carousel",$t="active",Ht=".active.carousel-item";class qt extends yt{constructor(e,t){super(e),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(t),this._indicatorsElement=At.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return St}static get NAME(){return kt}next(){this._slide(Dt)}nextWhenVisible(){!document.hidden&&We(this._element)&&this.next()}prev(){this._slide(Nt)}pause(e){e||(this._isPaused=!0),At.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(qe(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(e){e||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(e){this._activeElement=At.findOne(Ht,this._element);const t=this._getItemIndex(this._activeElement);if(e>this._items.length-1||e<0)return;if(this._isSliding)return void gt.one(this._element,It,(()=>this.to(e)));if(t===e)return this.pause(),void this.cycle();const n=e>t?Dt:Nt;this._slide(n,this._items[e])}_getConfig(e){return e={...St,...Ct.getDataAttributes(this._element),..."object"==typeof e?e:{}},Be(kt,e,Ot),e}_handleSwipe(){const e=Math.abs(this.touchDeltaX);if(e<=40)return;const t=e/this.touchDeltaX;this.touchDeltaX=0,t&&this._slide(t>0?jt:Lt)}_addEventListeners(){this._config.keyboard&>.on(this._element,"keydown.bs.carousel",(e=>this._keydown(e))),"hover"===this._config.pause&&(gt.on(this._element,"mouseenter.bs.carousel",(e=>this.pause(e))),gt.on(this._element,"mouseleave.bs.carousel",(e=>this.cycle(e)))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const e=e=>this._pointerEvent&&("pen"===e.pointerType||"touch"===e.pointerType),t=t=>{e(t)?this.touchStartX=t.clientX:this._pointerEvent||(this.touchStartX=t.touches[0].clientX)},n=e=>{this.touchDeltaX=e.touches&&e.touches.length>1?0:e.touches[0].clientX-this.touchStartX},i=t=>{e(t)&&(this.touchDeltaX=t.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((e=>this.cycle(e)),500+this._config.interval))};At.find(".carousel-item img",this._element).forEach((e=>{gt.on(e,"dragstart.bs.carousel",(e=>e.preventDefault()))})),this._pointerEvent?(gt.on(this._element,"pointerdown.bs.carousel",(e=>t(e))),gt.on(this._element,"pointerup.bs.carousel",(e=>i(e))),this._element.classList.add("pointer-event")):(gt.on(this._element,"touchstart.bs.carousel",(e=>t(e))),gt.on(this._element,"touchmove.bs.carousel",(e=>n(e))),gt.on(this._element,"touchend.bs.carousel",(e=>i(e))))}_keydown(e){if(/input|textarea/i.test(e.target.tagName))return;const t=Pt[e.key];t&&(e.preventDefault(),this._slide(t))}_getItemIndex(e){return this._items=e&&e.parentNode?At.find(".carousel-item",e.parentNode):[],this._items.indexOf(e)}_getItemByOrder(e,t){const n=e===Dt;return Ze(this._items,t,n,this._config.wrap)}_triggerSlideEvent(e,t){const n=this._getItemIndex(e),i=this._getItemIndex(At.findOne(Ht,this._element));return gt.trigger(this._element,"slide.bs.carousel",{relatedTarget:e,direction:t,from:i,to:n})}_setActiveIndicatorElement(e){if(this._indicatorsElement){const t=At.findOne(".active",this._indicatorsElement);t.classList.remove($t),t.removeAttribute("aria-current");const n=At.find("[data-bs-target]",this._indicatorsElement);for(let t=0;t{gt.trigger(this._element,It,{relatedTarget:o,direction:d,from:r,to:s})};if(this._element.classList.contains("slide")){o.classList.add(u),Ve(o),i.classList.add(c),o.classList.add(c);const e=()=>{o.classList.remove(c,u),o.classList.add($t),i.classList.remove($t,u,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(e,i,!0)}else i.classList.remove($t),o.classList.add($t),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(e){return[jt,Lt].includes(e)?Ke()?e===Lt?Nt:Dt:e===Lt?Dt:Nt:e}_orderToDirection(e){return[Dt,Nt].includes(e)?Ke()?e===Nt?Lt:jt:e===Nt?jt:Lt:e}static carouselInterface(e,t){const n=qt.getOrCreateInstance(e,t);let{_config:i}=n;"object"==typeof t&&(i={...i,...t});const r="string"==typeof t?t:i.slide;if("number"==typeof t)n.to(t);else if("string"==typeof r){if(void 0===n[r])throw new TypeError(`No method named "${r}"`);n[r]()}else i.interval&&i.ride&&(n.pause(),n.cycle())}static jQueryInterface(e){return this.each((function(){qt.carouselInterface(this,e)}))}static dataApiClickHandler(e){const t=He(this);if(!t||!t.classList.contains("carousel"))return;const n={...Ct.getDataAttributes(t),...Ct.getDataAttributes(this)},i=this.getAttribute("data-bs-slide-to");i&&(n.interval=!1),qt.carouselInterface(t,n),i&&qt.getInstance(t).to(i),e.preventDefault()}}gt.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",qt.dataApiClickHandler),gt.on(window,"load.bs.carousel.data-api",(()=>{const e=At.find('[data-bs-ride="carousel"]');for(let t=0,n=e.length;te===this._element));null!==i&&r.length&&(this._selector=i,this._triggerArray.push(t))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Bt}static get NAME(){return Mt}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let e,t=[];if(this._config.parent){const e=At.find(Xt,this._config.parent);t=At.find(".collapse.show, .collapse.collapsing",this._config.parent).filter((t=>!e.includes(t)))}const n=At.findOne(this._selector);if(t.length){const i=t.find((e=>n!==e));if(e=i?Kt.getInstance(i):null,e&&e._isTransitioning)return}if(gt.trigger(this._element,"show.bs.collapse").defaultPrevented)return;t.forEach((t=>{n!==t&&Kt.getOrCreateInstance(t,{toggle:!1}).hide(),e||vt.set(t,Rt,null)}));const i=this._getDimension();this._element.classList.remove(zt),this._element.classList.add(Ut),this._element.style[i]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const r=`scroll${i[0].toUpperCase()+i.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ut),this._element.classList.add(zt,Ft),this._element.style[i]="",gt.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[i]=`${this._element[r]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(gt.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const e=this._getDimension();this._element.style[e]=`${this._element.getBoundingClientRect()[e]}px`,Ve(this._element),this._element.classList.add(Ut),this._element.classList.remove(zt,Ft);const t=this._triggerArray.length;for(let e=0;e{this._isTransitioning=!1,this._element.classList.remove(Ut),this._element.classList.add(zt),gt.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(e=this._element){return e.classList.contains(Ft)}_getConfig(e){return(e={...Bt,...Ct.getDataAttributes(this._element),...e}).toggle=Boolean(e.toggle),e.parent=Re(e.parent),Be(Mt,e,Wt),e}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const e=At.find(Xt,this._config.parent);At.find(Yt,this._config.parent).filter((t=>!e.includes(t))).forEach((e=>{const t=He(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}))}_addAriaAndCollapsedClass(e,t){e.length&&e.forEach((e=>{t?e.classList.remove(Vt):e.classList.add(Vt),e.setAttribute("aria-expanded",t)}))}static jQueryInterface(e){return this.each((function(){const t={};"string"==typeof e&&/show|hide/.test(e)&&(t.toggle=!1);const n=Kt.getOrCreateInstance(this,t);if("string"==typeof e){if(void 0===n[e])throw new TypeError(`No method named "${e}"`);n[e]()}}))}}gt.on(document,"click.bs.collapse.data-api",Yt,(function(e){("A"===e.target.tagName||e.delegateTarget&&"A"===e.delegateTarget.tagName)&&e.preventDefault();const t=$e(this);At.find(t).forEach((e=>{Kt.getOrCreateInstance(e,{toggle:!1}).toggle()}))})),Qe(Kt);const Qt="dropdown",Gt="Escape",Jt="Space",Zt="ArrowUp",en="ArrowDown",tn=new RegExp("ArrowUp|ArrowDown|Escape"),nn="click.bs.dropdown.data-api",rn="keydown.bs.dropdown.data-api",on="show",sn='[data-bs-toggle="dropdown"]',an=".dropdown-menu",ln=Ke()?"top-end":"top-start",cn=Ke()?"top-start":"top-end",un=Ke()?"bottom-end":"bottom-start",dn=Ke()?"bottom-start":"bottom-end",fn=Ke()?"left-start":"right-start",hn=Ke()?"right-start":"left-start",pn={offset:[0,2],boundary:"clippingParents",reference:"toggle",display:"dynamic",popperConfig:null,autoClose:!0},gn={offset:"(array|string|function)",boundary:"(string|element)",reference:"(string|element|object)",display:"string",popperConfig:"(null|object|function)",autoClose:"(boolean|string)"};class mn extends yt{constructor(e,t){super(e),this._popper=null,this._config=this._getConfig(t),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar()}static get Default(){return pn}static get DefaultType(){return gn}static get NAME(){return Qt}toggle(){return this._isShown()?this.hide():this.show()}show(){if(Fe(this._element)||this._isShown(this._menu))return;const e={relatedTarget:this._element};if(gt.trigger(this._element,"show.bs.dropdown",e).defaultPrevented)return;const t=mn.getParentFromElement(this._element);this._inNavbar?Ct.setDataAttribute(this._menu,"popper","none"):this._createPopper(t),"ontouchstart"in document.documentElement&&!t.closest(".navbar-nav")&&[].concat(...document.body.children).forEach((e=>gt.on(e,"mouseover",Ue))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(on),this._element.classList.add(on),gt.trigger(this._element,"shown.bs.dropdown",e)}hide(){if(Fe(this._element)||!this._isShown(this._menu))return;const e={relatedTarget:this._element};this._completeHide(e)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(e){gt.trigger(this._element,"hide.bs.dropdown",e).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((e=>gt.off(e,"mouseover",Ue))),this._popper&&this._popper.destroy(),this._menu.classList.remove(on),this._element.classList.remove(on),this._element.setAttribute("aria-expanded","false"),Ct.removeDataAttribute(this._menu,"popper"),gt.trigger(this._element,"hidden.bs.dropdown",e))}_getConfig(e){if(e={...this.constructor.Default,...Ct.getDataAttributes(this._element),...e},Be(Qt,e,this.constructor.DefaultType),"object"==typeof e.reference&&!Me(e.reference)&&"function"!=typeof e.reference.getBoundingClientRect)throw new TypeError(`${Qt.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return e}_createPopper(e){if(void 0===i)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=e:Me(this._config.reference)?t=Re(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const n=this._getPopperConfig(),r=n.modifiers.find((e=>"applyStyles"===e.name&&!1===e.enabled));this._popper=Le(t,this._menu,n),r&&Ct.setDataAttribute(this._menu,"popper","static")}_isShown(e=this._element){return e.classList.contains(on)}_getMenuElement(){return At.next(this._element,an)[0]}_getPlacement(){const e=this._element.parentNode;if(e.classList.contains("dropend"))return fn;if(e.classList.contains("dropstart"))return hn;const t="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return e.classList.contains("dropup")?t?cn:ln:t?dn:un}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:e}=this._config;return"string"==typeof e?e.split(",").map((e=>Number.parseInt(e,10))):"function"==typeof e?t=>e(t,this._element):e}_getPopperConfig(){const e={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(e.modifiers=[{name:"applyStyles",enabled:!1}]),{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_selectMenuItem({key:e,target:t}){const n=At.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(We);n.length&&Ze(n,t,e===en,!n.includes(t)).focus()}static jQueryInterface(e){return this.each((function(){const t=mn.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e]()}}))}static clearMenus(e){if(e&&(2===e.button||"keyup"===e.type&&"Tab"!==e.key))return;const t=At.find(sn);for(let n=0,i=t.length;nt+e)),this._setElementAttributes(vn,"paddingRight",(t=>t+e)),this._setElementAttributes(yn,"marginRight",(t=>t-e))}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(e,t,n){const i=this.getWidth();this._applyManipulationCallback(e,(e=>{if(e!==this._element&&window.innerWidth>e.clientWidth+i)return;this._saveInitialAttribute(e,t);const r=window.getComputedStyle(e)[t];e.style[t]=`${n(Number.parseFloat(r))}px`}))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(vn,"paddingRight"),this._resetElementAttributes(yn,"marginRight")}_saveInitialAttribute(e,t){const n=e.style[t];n&&Ct.setDataAttribute(e,t,n)}_resetElementAttributes(e,t){this._applyManipulationCallback(e,(e=>{const n=Ct.getDataAttribute(e,t);void 0===n?e.style.removeProperty(t):(Ct.removeDataAttribute(e,t),e.style[t]=n)}))}_applyManipulationCallback(e,t){Me(e)?t(e):At.find(e,this._element).forEach(t)}isOverflowing(){return this.getWidth()>0}}const _n={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},wn={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"},xn="backdrop",En="show",Tn="mousedown.bs.backdrop";class Cn{constructor(e){this._config=this._getConfig(e),this._isAppended=!1,this._element=null}show(e){this._config.isVisible?(this._append(),this._config.isAnimated&&Ve(this._getElement()),this._getElement().classList.add(En),this._emulateAnimation((()=>{Ge(e)}))):Ge(e)}hide(e){this._config.isVisible?(this._getElement().classList.remove(En),this._emulateAnimation((()=>{this.dispose(),Ge(e)}))):Ge(e)}_getElement(){if(!this._element){const e=document.createElement("div");e.className=this._config.className,this._config.isAnimated&&e.classList.add("fade"),this._element=e}return this._element}_getConfig(e){return(e={..._n,..."object"==typeof e?e:{}}).rootElement=Re(e.rootElement),Be(xn,e,wn),e}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),gt.on(this._getElement(),Tn,(()=>{Ge(this._config.clickCallback)})),this._isAppended=!0)}dispose(){this._isAppended&&(gt.off(this._element,Tn),this._element.remove(),this._isAppended=!1)}_emulateAnimation(e){Je(e,this._getElement(),this._config.isAnimated)}}const An={trapElement:null,autofocus:!0},kn={trapElement:"element",autofocus:"boolean"},Sn=".bs.focustrap",On="backward";class Dn{constructor(e){this._config=this._getConfig(e),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:e,autofocus:t}=this._config;this._isActive||(t&&e.focus(),gt.off(document,Sn),gt.on(document,"focusin.bs.focustrap",(e=>this._handleFocusin(e))),gt.on(document,"keydown.tab.bs.focustrap",(e=>this._handleKeydown(e))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,gt.off(document,Sn))}_handleFocusin(e){const{target:t}=e,{trapElement:n}=this._config;if(t===document||t===n||n.contains(t))return;const i=At.focusableChildren(n);0===i.length?n.focus():this._lastTabNavDirection===On?i[i.length-1].focus():i[0].focus()}_handleKeydown(e){"Tab"===e.key&&(this._lastTabNavDirection=e.shiftKey?On:"forward")}_getConfig(e){return e={...An,..."object"==typeof e?e:{}},Be("focustrap",e,kn),e}}const Nn="modal",Ln=".bs.modal",jn="Escape",Pn={backdrop:!0,keyboard:!0,focus:!0},In={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"},$n="hidden.bs.modal",Hn="show.bs.modal",qn="resize.bs.modal",Mn="click.dismiss.bs.modal",Rn="keydown.dismiss.bs.modal",Bn="mousedown.dismiss.bs.modal",Wn="modal-open",Fn="show",zn="modal-static";class Un extends yt{constructor(e,t){super(e),this._config=this._getConfig(t),this._dialog=At.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new bn}static get Default(){return Pn}static get NAME(){return Nn}toggle(e){return this._isShown?this.hide():this.show(e)}show(e){if(this._isShown||this._isTransitioning)return;gt.trigger(this._element,Hn,{relatedTarget:e}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(Wn),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),gt.on(this._dialog,Bn,(()=>{gt.one(this._element,"mouseup.dismiss.bs.modal",(e=>{e.target===this._element&&(this._ignoreBackdropClick=!0)}))})),this._showBackdrop((()=>this._showElement(e))))}hide(){if(!this._isShown||this._isTransitioning)return;if(gt.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const e=this._isAnimated();e&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove(Fn),gt.off(this._element,Mn),gt.off(this._dialog,Bn),this._queueCallback((()=>this._hideModal()),this._element,e)}dispose(){[window,this._dialog].forEach((e=>gt.off(e,Ln))),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Cn({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Dn({trapElement:this._element})}_getConfig(e){return e={...Pn,...Ct.getDataAttributes(this._element),..."object"==typeof e?e:{}},Be(Nn,e,In),e}_showElement(e){const t=this._isAnimated(),n=At.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,n&&(n.scrollTop=0),t&&Ve(this._element),this._element.classList.add(Fn);this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,gt.trigger(this._element,"shown.bs.modal",{relatedTarget:e})}),this._dialog,t)}_setEscapeEvent(){this._isShown?gt.on(this._element,Rn,(e=>{this._config.keyboard&&e.key===jn?(e.preventDefault(),this.hide()):this._config.keyboard||e.key!==jn||this._triggerBackdropTransition()})):gt.off(this._element,Rn)}_setResizeEvent(){this._isShown?gt.on(window,qn,(()=>this._adjustDialog())):gt.off(window,qn)}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Wn),this._resetAdjustments(),this._scrollBar.reset(),gt.trigger(this._element,$n)}))}_showBackdrop(e){gt.on(this._element,Mn,(e=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:e.target===e.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())})),this._backdrop.show(e)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(gt.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:e,scrollHeight:t,style:n}=this._element,i=t>document.documentElement.clientHeight;!i&&"hidden"===n.overflowY||e.contains(zn)||(i||(n.overflowY="hidden"),e.add(zn),this._queueCallback((()=>{e.remove(zn),i||this._queueCallback((()=>{n.overflowY=""}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const e=this._element.scrollHeight>document.documentElement.clientHeight,t=this._scrollBar.getWidth(),n=t>0;(!n&&e&&!Ke()||n&&!e&&Ke())&&(this._element.style.paddingLeft=`${t}px`),(n&&!e&&!Ke()||!n&&e&&Ke())&&(this._element.style.paddingRight=`${t}px`)}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(e,t){return this.each((function(){const n=Un.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===n[e])throw new TypeError(`No method named "${e}"`);n[e](t)}}))}}gt.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(e){const t=He(this);["A","AREA"].includes(this.tagName)&&e.preventDefault(),gt.one(t,Hn,(e=>{e.defaultPrevented||gt.one(t,$n,(()=>{We(this)&&this.focus()}))}));const n=At.findOne(".modal.show");n&&Un.getInstance(n).hide();Un.getOrCreateInstance(t).toggle(this)})),bt(Un),Qe(Un);const Vn="offcanvas",Xn={backdrop:!0,keyboard:!0,scroll:!1},Yn={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"},Kn="show",Qn=".offcanvas.show",Gn="hidden.bs.offcanvas";class Jn extends yt{constructor(e,t){super(e),this._config=this._getConfig(t),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return Vn}static get Default(){return Xn}toggle(e){return this._isShown?this.hide():this.show(e)}show(e){if(this._isShown)return;if(gt.trigger(this._element,"show.bs.offcanvas",{relatedTarget:e}).defaultPrevented)return;this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new bn).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Kn);this._queueCallback((()=>{this._config.scroll||this._focustrap.activate(),gt.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:e})}),this._element,!0)}hide(){if(!this._isShown)return;if(gt.trigger(this._element,"hide.bs.offcanvas").defaultPrevented)return;this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove(Kn),this._backdrop.hide();this._queueCallback((()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new bn).reset(),gt.trigger(this._element,Gn)}),this._element,!0)}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(e){return e={...Xn,...Ct.getDataAttributes(this._element),..."object"==typeof e?e:{}},Be(Vn,e,Yn),e}_initializeBackDrop(){return new Cn({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Dn({trapElement:this._element})}_addEventListeners(){gt.on(this._element,"keydown.dismiss.bs.offcanvas",(e=>{this._config.keyboard&&"Escape"===e.key&&this.hide()}))}static jQueryInterface(e){return this.each((function(){const t=Jn.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e]||e.startsWith("_")||"constructor"===e)throw new TypeError(`No method named "${e}"`);t[e](this)}}))}}gt.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(e){const t=He(this);if(["A","AREA"].includes(this.tagName)&&e.preventDefault(),Fe(this))return;gt.one(t,Gn,(()=>{We(this)&&this.focus()}));const n=At.findOne(Qn);n&&n!==t&&Jn.getInstance(n).hide();Jn.getOrCreateInstance(t).toggle(this)})),gt.on(window,"load.bs.offcanvas.data-api",(()=>At.find(Qn).forEach((e=>Jn.getOrCreateInstance(e).show())))),bt(Jn),Qe(Jn);const Zn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),ei=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,ti=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,ni=(e,t)=>{const n=e.nodeName.toLowerCase();if(t.includes(n))return!Zn.has(n)||Boolean(ei.test(e.nodeValue)||ti.test(e.nodeValue));const i=t.filter((e=>e instanceof RegExp));for(let e=0,t=i.length;e{ni(e,s)||n.removeAttribute(e.nodeName)}))}return i.body.innerHTML}const oi="tooltip",si=new Set(["sanitize","allowList","sanitizeFn"]),ai={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},li={AUTO:"auto",TOP:"top",RIGHT:Ke()?"left":"right",BOTTOM:"bottom",LEFT:Ke()?"right":"left"},ci={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:ii,popperConfig:null},ui={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},di="fade",fi="show",hi="show",pi="out",gi=".tooltip-inner",mi=".modal",vi="hide.bs.modal",yi="hover",bi="focus";class _i extends yt{constructor(e,t){if(void 0===i)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(e),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(t),this.tip=null,this._setListeners()}static get Default(){return ci}static get NAME(){return oi}static get Event(){return ui}static get DefaultType(){return ai}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(e){if(this._isEnabled)if(e){const t=this._initializeOnDelegatedTarget(e);t._activeTrigger.click=!t._activeTrigger.click,t._isWithActiveTrigger()?t._enter(null,t):t._leave(null,t)}else{if(this.getTipElement().classList.contains(fi))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),gt.off(this._element.closest(mi),vi,this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const e=gt.trigger(this._element,this.constructor.Event.SHOW),t=ze(this._element),n=null===t?this._element.ownerDocument.documentElement.contains(this._element):t.contains(this._element);if(e.defaultPrevented||!n)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(gi).innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const i=this.getTipElement(),r=(e=>{do{e+=Math.floor(1e6*Math.random())}while(document.getElementById(e));return e})(this.constructor.NAME);i.setAttribute("id",r),this._element.setAttribute("aria-describedby",r),this._config.animation&&i.classList.add(di);const o="function"==typeof this._config.placement?this._config.placement.call(this,i,this._element):this._config.placement,s=this._getAttachment(o);this._addAttachmentClass(s);const{container:a}=this._config;vt.set(i,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(i),gt.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=Le(this._element,i,this._getPopperConfig(s)),i.classList.add(fi);const l=this._resolvePossibleFunction(this._config.customClass);l&&i.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((e=>{gt.on(e,"mouseover",Ue)}));const c=this.tip.classList.contains(di);this._queueCallback((()=>{const e=this._hoverState;this._hoverState=null,gt.trigger(this._element,this.constructor.Event.SHOWN),e===pi&&this._leave(null,this)}),this.tip,c)}hide(){if(!this._popper)return;const e=this.getTipElement();if(gt.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;e.classList.remove(fi),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((e=>gt.off(e,"mouseover",Ue))),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const t=this.tip.classList.contains(di);this._queueCallback((()=>{this._isWithActiveTrigger()||(this._hoverState!==hi&&e.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),gt.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())}),this.tip,t),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const e=document.createElement("div");e.innerHTML=this._config.template;const t=e.children[0];return this.setContent(t),t.classList.remove(di,fi),this.tip=t,this.tip}setContent(e){this._sanitizeAndSetContent(e,this.getTitle(),gi)}_sanitizeAndSetContent(e,t,n){const i=At.findOne(n,e);t||!i?this.setElementContent(i,t):i.remove()}setElementContent(e,t){if(null!==e)return Me(t)?(t=Re(t),void(this._config.html?t.parentNode!==e&&(e.innerHTML="",e.append(t)):e.textContent=t.textContent)):void(this._config.html?(this._config.sanitize&&(t=ri(t,this._config.allowList,this._config.sanitizeFn)),e.innerHTML=t):e.textContent=t)}getTitle(){const e=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(e)}updateAttachment(e){return"right"===e?"end":"left"===e?"start":e}_initializeOnDelegatedTarget(e,t){return t||this.constructor.getOrCreateInstance(e.delegateTarget,this._getDelegateConfig())}_getOffset(){const{offset:e}=this._config;return"string"==typeof e?e.split(",").map((e=>Number.parseInt(e,10))):"function"==typeof e?t=>e(t,this._element):e}_resolvePossibleFunction(e){return"function"==typeof e?e.call(this._element):e}_getPopperConfig(e){const t={placement:e,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:e=>this._handlePopperPlacementChange(e)}],onFirstUpdate:e=>{e.options.placement!==e.placement&&this._handlePopperPlacementChange(e)}};return{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_addAttachmentClass(e){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(e)}`)}_getAttachment(e){return li[e.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach((e=>{if("click"===e)gt.on(this._element,this.constructor.Event.CLICK,this._config.selector,(e=>this.toggle(e)));else if("manual"!==e){const t=e===yi?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,n=e===yi?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;gt.on(this._element,t,this._config.selector,(e=>this._enter(e))),gt.on(this._element,n,this._config.selector,(e=>this._leave(e)))}})),this._hideModalHandler=()=>{this._element&&this.hide()},gt.on(this._element.closest(mi),vi,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const e=this._element.getAttribute("title"),t=typeof this._element.getAttribute("data-bs-original-title");(e||"string"!==t)&&(this._element.setAttribute("data-bs-original-title",e||""),!e||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",e),this._element.setAttribute("title",""))}_enter(e,t){t=this._initializeOnDelegatedTarget(e,t),e&&(t._activeTrigger["focusin"===e.type?bi:yi]=!0),t.getTipElement().classList.contains(fi)||t._hoverState===hi?t._hoverState=hi:(clearTimeout(t._timeout),t._hoverState=hi,t._config.delay&&t._config.delay.show?t._timeout=setTimeout((()=>{t._hoverState===hi&&t.show()}),t._config.delay.show):t.show())}_leave(e,t){t=this._initializeOnDelegatedTarget(e,t),e&&(t._activeTrigger["focusout"===e.type?bi:yi]=t._element.contains(e.relatedTarget)),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=pi,t._config.delay&&t._config.delay.hide?t._timeout=setTimeout((()=>{t._hoverState===pi&&t.hide()}),t._config.delay.hide):t.hide())}_isWithActiveTrigger(){for(const e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1}_getConfig(e){const t=Ct.getDataAttributes(this._element);return Object.keys(t).forEach((e=>{si.has(e)&&delete t[e]})),(e={...this.constructor.Default,...t,..."object"==typeof e&&e?e:{}}).container=!1===e.container?document.body:Re(e.container),"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),Be(oi,e,this.constructor.DefaultType),e.sanitize&&(e.template=ri(e.template,e.allowList,e.sanitizeFn)),e}_getDelegateConfig(){const e={};for(const t in this._config)this.constructor.Default[t]!==this._config[t]&&(e[t]=this._config[t]);return e}_cleanTipClass(){const e=this.getTipElement(),t=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),n=e.getAttribute("class").match(t);null!==n&&n.length>0&&n.map((e=>e.trim())).forEach((t=>e.classList.remove(t)))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(e){const{state:t}=e;t&&(this.tip=t.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(t.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(e){return this.each((function(){const t=_i.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e]()}}))}}Qe(_i);const wi={..._i.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},xi={..._i.DefaultType,content:"(string|element|function)"},Ei={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class Ti extends _i{static get Default(){return wi}static get NAME(){return"popover"}static get Event(){return Ei}static get DefaultType(){return xi}isWithContent(){return this.getTitle()||this._getContent()}setContent(e){this._sanitizeAndSetContent(e,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(e,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(e){return this.each((function(){const t=Ti.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e]()}}))}}Qe(Ti);const Ci="scrollspy",Ai=".bs.scrollspy",ki={offset:10,method:"auto",target:""},Si={offset:"number",method:"string",target:"(string|element)"},Oi="dropdown-item",Di="active",Ni=".nav-link",Li=".nav-link, .list-group-item, .dropdown-item",ji="position";class Pi extends yt{constructor(e,t){super(e),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(t),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,gt.on(this._scrollElement,"scroll.bs.scrollspy",(()=>this._process())),this.refresh(),this._process()}static get Default(){return ki}static get NAME(){return Ci}refresh(){const e=this._scrollElement===this._scrollElement.window?"offset":ji,t="auto"===this._config.method?e:this._config.method,n=t===ji?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight();At.find(Li,this._config.target).map((e=>{const i=$e(e),r=i?At.findOne(i):null;if(r){const e=r.getBoundingClientRect();if(e.width||e.height)return[Ct[t](r).top+n,i]}return null})).filter((e=>e)).sort(((e,t)=>e[0]-t[0])).forEach((e=>{this._offsets.push(e[0]),this._targets.push(e[1])}))}dispose(){gt.off(this._scrollElement,Ai),super.dispose()}_getConfig(e){return(e={...ki,...Ct.getDataAttributes(this._element),..."object"==typeof e&&e?e:{}}).target=Re(e.target)||document.documentElement,Be(Ci,e,Si),e}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const e=this._getScrollTop()+this._config.offset,t=this._getScrollHeight(),n=this._config.offset+t-this._getOffsetHeight();if(this._scrollHeight!==t&&this.refresh(),e>=n){const e=this._targets[this._targets.length-1];this._activeTarget!==e&&this._activate(e)}else{if(this._activeTarget&&e0)return this._activeTarget=null,void this._clear();for(let t=this._offsets.length;t--;){this._activeTarget!==this._targets[t]&&e>=this._offsets[t]&&(void 0===this._offsets[t+1]||e`${t}[data-bs-target="${e}"],${t}[href="${e}"]`)),n=At.findOne(t.join(","),this._config.target);n.classList.add(Di),n.classList.contains(Oi)?At.findOne(".dropdown-toggle",n.closest(".dropdown")).classList.add(Di):At.parents(n,".nav, .list-group").forEach((e=>{At.prev(e,".nav-link, .list-group-item").forEach((e=>e.classList.add(Di))),At.prev(e,".nav-item").forEach((e=>{At.children(e,Ni).forEach((e=>e.classList.add(Di)))}))})),gt.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:e})}_clear(){At.find(Li,this._config.target).filter((e=>e.classList.contains(Di))).forEach((e=>e.classList.remove(Di)))}static jQueryInterface(e){return this.each((function(){const t=Pi.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e]()}}))}}gt.on(window,"load.bs.scrollspy.data-api",(()=>{At.find('[data-bs-spy="scroll"]').forEach((e=>new Pi(e)))})),Qe(Pi);const Ii="active",$i="fade",Hi="show",qi=".active",Mi=":scope > li > .active";class Ri extends yt{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(Ii))return;let e;const t=He(this._element),n=this._element.closest(".nav, .list-group");if(n){const t="UL"===n.nodeName||"OL"===n.nodeName?Mi:qi;e=At.find(t,n),e=e[e.length-1]}const i=e?gt.trigger(e,"hide.bs.tab",{relatedTarget:this._element}):null;if(gt.trigger(this._element,"show.bs.tab",{relatedTarget:e}).defaultPrevented||null!==i&&i.defaultPrevented)return;this._activate(this._element,n);const r=()=>{gt.trigger(e,"hidden.bs.tab",{relatedTarget:this._element}),gt.trigger(this._element,"shown.bs.tab",{relatedTarget:e})};t?this._activate(t,t.parentNode,r):r()}_activate(e,t,n){const i=(!t||"UL"!==t.nodeName&&"OL"!==t.nodeName?At.children(t,qi):At.find(Mi,t))[0],r=n&&i&&i.classList.contains($i),o=()=>this._transitionComplete(e,i,n);i&&r?(i.classList.remove(Hi),this._queueCallback(o,e,!0)):o()}_transitionComplete(e,t,n){if(t){t.classList.remove(Ii);const e=At.findOne(":scope > .dropdown-menu .active",t.parentNode);e&&e.classList.remove(Ii),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!1)}e.classList.add(Ii),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!0),Ve(e),e.classList.contains($i)&&e.classList.add(Hi);let i=e.parentNode;if(i&&"LI"===i.nodeName&&(i=i.parentNode),i&&i.classList.contains("dropdown-menu")){const t=e.closest(".dropdown");t&&At.find(".dropdown-toggle",t).forEach((e=>e.classList.add(Ii))),e.setAttribute("aria-expanded",!0)}n&&n()}static jQueryInterface(e){return this.each((function(){const t=Ri.getOrCreateInstance(this);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e]()}}))}}gt.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(e){if(["A","AREA"].includes(this.tagName)&&e.preventDefault(),Fe(this))return;Ri.getOrCreateInstance(this).show()})),Qe(Ri);const Bi="toast",Wi="hide",Fi="show",zi="showing",Ui={animation:"boolean",autohide:"boolean",delay:"number"},Vi={animation:!0,autohide:!0,delay:5e3};class Xi extends yt{constructor(e,t){super(e),this._config=this._getConfig(t),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Ui}static get Default(){return Vi}static get NAME(){return Bi}show(){if(gt.trigger(this._element,"show.bs.toast").defaultPrevented)return;this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");this._element.classList.remove(Wi),Ve(this._element),this._element.classList.add(Fi),this._element.classList.add(zi),this._queueCallback((()=>{this._element.classList.remove(zi),gt.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation)}hide(){if(!this._element.classList.contains(Fi))return;if(gt.trigger(this._element,"hide.bs.toast").defaultPrevented)return;this._element.classList.add(zi),this._queueCallback((()=>{this._element.classList.add(Wi),this._element.classList.remove(zi),this._element.classList.remove(Fi),gt.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)}dispose(){this._clearTimeout(),this._element.classList.contains(Fi)&&this._element.classList.remove(Fi),super.dispose()}_getConfig(e){return e={...Vi,...Ct.getDataAttributes(this._element),..."object"==typeof e&&e?e:{}},Be(Bi,e,this.constructor.DefaultType),e}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(e,t){switch(e.type){case"mouseover":case"mouseout":this._hasMouseInteraction=t;break;case"focusin":case"focusout":this._hasKeyboardInteraction=t}if(t)return void this._clearTimeout();const n=e.relatedTarget;this._element===n||this._element.contains(n)||this._maybeScheduleHide()}_setListeners(){gt.on(this._element,"mouseover.bs.toast",(e=>this._onInteraction(e,!0))),gt.on(this._element,"mouseout.bs.toast",(e=>this._onInteraction(e,!1))),gt.on(this._element,"focusin.bs.toast",(e=>this._onInteraction(e,!0))),gt.on(this._element,"focusout.bs.toast",(e=>this._onInteraction(e,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(e){return this.each((function(){const t=Xi.getOrCreateInstance(this,e);if("string"==typeof e){if(void 0===t[e])throw new TypeError(`No method named "${e}"`);t[e](this)}}))}}bt(Xi),Qe(Xi),n.g.$=n(755),$(document).ready((function(){window.$theme="Froxlor",window.$session=$('meta[name="froxlor-session"]').attr("content")})),n(511),n(470),n(414),n(444),n(786),n(960)},755:function(e,t){var n;!function(t,n){"use strict";"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,(function(i,r){"use strict";var o=[],s=Object.getPrototypeOf,a=o.slice,l=o.flat?function(e){return o.flat.call(e)}:function(e){return o.concat.apply([],e)},c=o.push,u=o.indexOf,d={},f=d.toString,h=d.hasOwnProperty,p=h.toString,g=p.call(Object),m={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},b=i.document,_={type:!0,src:!0,nonce:!0,noModule:!0};function w(e,t,n){var i,r,o=(n=n||b).createElement("script");if(o.text=e,t)for(i in _)(r=t[i]||t.getAttribute&&t.getAttribute(i))&&o.setAttribute(i,r);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?d[f.call(e)]||"object":typeof e}var E="3.6.0",T=function(e,t){return new T.fn.init(e,t)};function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}T.fn=T.prototype={jquery:E,constructor:T,length:0,toArray:function(){return a.call(this)},get:function(e){return null==e?a.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=T.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return T.each(this,e)},map:function(e){return this.pushStack(T.map(this,(function(t,n){return e.call(t,n,t)})))},slice:function(){return this.pushStack(a.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(T.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(T.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|[\\x20\\t\\r\\n\\f])[\\x20\\t\\r\\n\\f]*"),U=new RegExp(H+"|>"),V=new RegExp(R),X=new RegExp("^"+q+"$"),Y={ID:new RegExp("^#("+q+")"),CLASS:new RegExp("^\\.("+q+")"),TAG:new RegExp("^("+q+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+R),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\([\\x20\\t\\r\\n\\f]*(even|odd|(([+-]|)(\\d*)n|)[\\x20\\t\\r\\n\\f]*(?:([+-]|)[\\x20\\t\\r\\n\\f]*(\\d+)|))[\\x20\\t\\r\\n\\f]*\\)|)","i"),bool:new RegExp("^(?:"+$+")$","i"),needsContext:new RegExp("^[\\x20\\t\\r\\n\\f]*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\([\\x20\\t\\r\\n\\f]*((?:-\\d)?\\d*)[\\x20\\t\\r\\n\\f]*\\)|)(?=[^-]|$)","i")},K=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,G=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}[\\x20\\t\\r\\n\\f]?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},ie=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,re=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){f()},se=_e((function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{j.apply(D=P.call(w.childNodes),w.childNodes),D[w.childNodes.length].nodeType}catch(e){j={apply:D.length?function(e,t){L.apply(e,P.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}function ae(e,t,i,r){var o,a,c,u,d,p,v,y=t&&t.ownerDocument,w=t?t.nodeType:9;if(i=i||[],"string"!=typeof e||!e||1!==w&&9!==w&&11!==w)return i;if(!r&&(f(t),t=t||h,g)){if(11!==w&&(d=Z.exec(e)))if(o=d[1]){if(9===w){if(!(c=t.getElementById(o)))return i;if(c.id===o)return i.push(c),i}else if(y&&(c=y.getElementById(o))&&b(t,c)&&c.id===o)return i.push(c),i}else{if(d[2])return j.apply(i,t.getElementsByTagName(e)),i;if((o=d[3])&&n.getElementsByClassName&&t.getElementsByClassName)return j.apply(i,t.getElementsByClassName(o)),i}if(n.qsa&&!k[e+" "]&&(!m||!m.test(e))&&(1!==w||"object"!==t.nodeName.toLowerCase())){if(v=e,y=t,1===w&&(U.test(e)||z.test(e))){for((y=ee.test(e)&&ve(t.parentNode)||t)===t&&n.scope||((u=t.getAttribute("id"))?u=u.replace(ie,re):t.setAttribute("id",u=_)),a=(p=s(e)).length;a--;)p[a]=(u?"#"+u:":scope")+" "+be(p[a]);v=p.join(",")}try{return j.apply(i,y.querySelectorAll(v)),i}catch(t){k(e,!0)}finally{u===_&&t.removeAttribute("id")}}}return l(e.replace(W,"$1"),t,i,r)}function le(){var e=[];return function t(n,r){return e.push(n+" ")>i.cacheLength&&delete t[e.shift()],t[n+" "]=r}}function ce(e){return e[_]=!0,e}function ue(e){var t=h.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function de(e,t){for(var n=e.split("|"),r=n.length;r--;)i.attrHandle[n[r]]=t}function fe(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function he(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ge(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&se(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function me(e){return ce((function(t){return t=+t,ce((function(n,i){for(var r,o=e([],n.length,t),s=o.length;s--;)n[r=o[s]]&&(n[r]=!(i[r]=n[r]))}))}))}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in n=ae.support={},o=ae.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!K.test(t||n&&n.nodeName||"HTML")},f=ae.setDocument=function(e){var t,r,s=e?e.ownerDocument||e:w;return s!=h&&9===s.nodeType&&s.documentElement?(p=(h=s).documentElement,g=!o(h),w!=h&&(r=h.defaultView)&&r.top!==r&&(r.addEventListener?r.addEventListener("unload",oe,!1):r.attachEvent&&r.attachEvent("onunload",oe)),n.scope=ue((function(e){return p.appendChild(e).appendChild(h.createElement("div")),void 0!==e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length})),n.attributes=ue((function(e){return e.className="i",!e.getAttribute("className")})),n.getElementsByTagName=ue((function(e){return e.appendChild(h.createComment("")),!e.getElementsByTagName("*").length})),n.getElementsByClassName=J.test(h.getElementsByClassName),n.getById=ue((function(e){return p.appendChild(e).id=_,!h.getElementsByName||!h.getElementsByName(_).length})),n.getById?(i.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},i.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(i.filter.ID=function(e){var t=e.replace(te,ne);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},i.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n,i,r,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(r=t.getElementsByName(e),i=0;o=r[i++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),i.find.TAG=n.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[r++];)1===n.nodeType&&i.push(n);return i}return o},i.find.CLASS=n.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],m=[],(n.qsa=J.test(h.querySelectorAll))&&(ue((function(e){var t;p.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&m.push("[*^$]=[\\x20\\t\\r\\n\\f]*(?:''|\"\")"),e.querySelectorAll("[selected]").length||m.push("\\[[\\x20\\t\\r\\n\\f]*(?:value|"+$+")"),e.querySelectorAll("[id~="+_+"-]").length||m.push("~="),(t=h.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||m.push("\\[[\\x20\\t\\r\\n\\f]*name[\\x20\\t\\r\\n\\f]*=[\\x20\\t\\r\\n\\f]*(?:''|\"\")"),e.querySelectorAll(":checked").length||m.push(":checked"),e.querySelectorAll("a#"+_+"+*").length||m.push(".#.+[+~]"),e.querySelectorAll("\\\f"),m.push("[\\r\\n\\f]")})),ue((function(e){e.innerHTML="";var t=h.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&m.push("name[\\x20\\t\\r\\n\\f]*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&m.push(":enabled",":disabled"),p.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&m.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),m.push(",.*:")}))),(n.matchesSelector=J.test(y=p.matches||p.webkitMatchesSelector||p.mozMatchesSelector||p.oMatchesSelector||p.msMatchesSelector))&&ue((function(e){n.disconnectedMatch=y.call(e,"*"),y.call(e,"[s!='']:x"),v.push("!=",R)})),m=m.length&&new RegExp(m.join("|")),v=v.length&&new RegExp(v.join("|")),t=J.test(p.compareDocumentPosition),b=t||J.test(p.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},S=t?function(e,t){if(e===t)return d=!0,0;var i=!e.compareDocumentPosition-!t.compareDocumentPosition;return i||(1&(i=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===i?e==h||e.ownerDocument==w&&b(w,e)?-1:t==h||t.ownerDocument==w&&b(w,t)?1:u?I(u,e)-I(u,t):0:4&i?-1:1)}:function(e,t){if(e===t)return d=!0,0;var n,i=0,r=e.parentNode,o=t.parentNode,s=[e],a=[t];if(!r||!o)return e==h?-1:t==h?1:r?-1:o?1:u?I(u,e)-I(u,t):0;if(r===o)return fe(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)a.unshift(n);for(;s[i]===a[i];)i++;return i?fe(s[i],a[i]):s[i]==w?-1:a[i]==w?1:0},h):h},ae.matches=function(e,t){return ae(e,null,null,t)},ae.matchesSelector=function(e,t){if(f(e),n.matchesSelector&&g&&!k[t+" "]&&(!v||!v.test(t))&&(!m||!m.test(t)))try{var i=y.call(e,t);if(i||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return i}catch(e){k(t,!0)}return ae(t,h,null,[e]).length>0},ae.contains=function(e,t){return(e.ownerDocument||e)!=h&&f(e),b(e,t)},ae.attr=function(e,t){(e.ownerDocument||e)!=h&&f(e);var r=i.attrHandle[t.toLowerCase()],o=r&&O.call(i.attrHandle,t.toLowerCase())?r(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},ae.escape=function(e){return(e+"").replace(ie,re)},ae.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},ae.uniqueSort=function(e){var t,i=[],r=0,o=0;if(d=!n.detectDuplicates,u=!n.sortStable&&e.slice(0),e.sort(S),d){for(;t=e[o++];)t===e[o]&&(r=i.push(o));for(;r--;)e.splice(i[r],1)}return u=null,e},r=ae.getText=function(e){var t,n="",i=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=r(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[i++];)n+=r(t);return n},i=ae.selectors={cacheLength:50,createPseudo:ce,match:Y,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ae.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ae.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Y.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=s(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=T[e+" "];return t||(t=new RegExp("(^|[\\x20\\t\\r\\n\\f])"+e+"("+H+"|$)"))&&T(e,(function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,n){return function(i){var r=ae.attr(i,e);return null==r?"!="===t:!t||(r+="","="===t?r===n:"!="===t?r!==n:"^="===t?n&&0===r.indexOf(n):"*="===t?n&&r.indexOf(n)>-1:"$="===t?n&&r.slice(-n.length)===n:"~="===t?(" "+r.replace(B," ")+" ").indexOf(n)>-1:"|="===t&&(r===n||r.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,i,r){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===i&&0===r?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,f,h,p,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),y=!l&&!a,b=!1;if(m){if(o){for(;g;){for(f=t;f=f[g];)if(a?f.nodeName.toLowerCase()===v:1===f.nodeType)return!1;p=g="only"===e&&!p&&"nextSibling"}return!0}if(p=[s?m.firstChild:m.lastChild],s&&y){for(b=(h=(c=(u=(d=(f=m)[_]||(f[_]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]||[])[0]===x&&c[1])&&c[2],f=h&&m.childNodes[h];f=++h&&f&&f[g]||(b=h=0)||p.pop();)if(1===f.nodeType&&++b&&f===t){u[e]=[x,h,b];break}}else if(y&&(b=h=(c=(u=(d=(f=t)[_]||(f[_]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]||[])[0]===x&&c[1]),!1===b)for(;(f=++h&&f&&f[g]||(b=h=0)||p.pop())&&((a?f.nodeName.toLowerCase()!==v:1!==f.nodeType)||!++b||(y&&((u=(d=f[_]||(f[_]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]=[x,b]),f!==t)););return(b-=r)===i||b%i==0&&b/i>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||ae.error("unsupported pseudo: "+e);return r[_]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ce((function(e,n){for(var i,o=r(e,t),s=o.length;s--;)e[i=I(e,o[s])]=!(n[i]=o[s])})):function(e){return r(e,0,n)}):r}},pseudos:{not:ce((function(e){var t=[],n=[],i=a(e.replace(W,"$1"));return i[_]?ce((function(e,t,n,r){for(var o,s=i(e,null,r,[]),a=e.length;a--;)(o=s[a])&&(e[a]=!(t[a]=o))})):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}})),has:ce((function(e){return function(t){return ae(e,t).length>0}})),contains:ce((function(e){return e=e.replace(te,ne),function(t){return(t.textContent||r(t)).indexOf(e)>-1}})),lang:ce((function(e){return X.test(e||"")||ae.error("unsupported lang: "+e),e=e.replace(te,ne).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===p},focus:function(e){return e===h.activeElement&&(!h.hasFocus||h.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return G.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:me((function(){return[0]})),last:me((function(e,t){return[t-1]})),eq:me((function(e,t,n){return[n<0?n+t:n]})),even:me((function(e,t){for(var n=0;nt?t:n;--i>=0;)e.push(i);return e})),gt:me((function(e,t,n){for(var i=n<0?n+t:n;++i1?function(t,n,i){for(var r=e.length;r--;)if(!e[r](t,n,i))return!1;return!0}:e[0]}function xe(e,t,n,i,r){for(var o,s=[],a=0,l=e.length,c=null!=t;a-1&&(o[c]=!(s[c]=d))}}else v=xe(v===s?v.splice(p,v.length):v),r?r(null,s,v,l):j.apply(s,v)}))}function Te(e){for(var t,n,r,o=e.length,s=i.relative[e[0].type],a=s||i.relative[" "],l=s?1:0,u=_e((function(e){return e===t}),a,!0),d=_e((function(e){return I(t,e)>-1}),a,!0),f=[function(e,n,i){var r=!s&&(i||n!==c)||((t=n).nodeType?u(e,n,i):d(e,n,i));return t=null,r}];l1&&we(f),l>1&&be(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(W,"$1"),n,l0,r=e.length>0,o=function(o,s,a,l,u){var d,p,m,v=0,y="0",b=o&&[],_=[],w=c,E=o||r&&i.find.TAG("*",u),T=x+=null==w?1:Math.random()||.1,C=E.length;for(u&&(c=s==h||s||u);y!==C&&null!=(d=E[y]);y++){if(r&&d){for(p=0,s||d.ownerDocument==h||(f(d),a=!g);m=e[p++];)if(m(d,s||h,a)){l.push(d);break}u&&(x=T)}n&&((d=!m&&d)&&v--,o&&b.push(d))}if(v+=y,n&&y!==v){for(p=0;m=t[p++];)m(b,_,s,a);if(o){if(v>0)for(;y--;)b[y]||_[y]||(_[y]=N.call(l));_=xe(_)}j.apply(l,_),u&&!o&&_.length>0&&v+t.length>1&&ae.uniqueSort(l)}return u&&(x=T,c=w),b};return n?ce(o):o}(o,r)),a.selector=e}return a},l=ae.select=function(e,t,n,r){var o,l,c,u,d,f="function"==typeof e&&e,h=!r&&s(e=f.selector||e);if(n=n||[],1===h.length){if((l=h[0]=h[0].slice(0)).length>2&&"ID"===(c=l[0]).type&&9===t.nodeType&&g&&i.relative[l[1].type]){if(!(t=(i.find.ID(c.matches[0].replace(te,ne),t)||[])[0]))return n;f&&(t=t.parentNode),e=e.slice(l.shift().value.length)}for(o=Y.needsContext.test(e)?0:l.length;o--&&(c=l[o],!i.relative[u=c.type]);)if((d=i.find[u])&&(r=d(c.matches[0].replace(te,ne),ee.test(l[0].type)&&ve(t.parentNode)||t))){if(l.splice(o,1),!(e=r.length&&be(l)))return j.apply(n,r),n;break}}return(f||a(e,h))(r,t,!g,n,!t||ee.test(e)&&ve(t.parentNode)||t),n},n.sortStable=_.split("").sort(S).join("")===_,n.detectDuplicates=!!d,f(),n.sortDetached=ue((function(e){return 1&e.compareDocumentPosition(h.createElement("fieldset"))})),ue((function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")}))||de("type|href|height|width",(function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)})),n.attributes&&ue((function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")}))||de("value",(function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue})),ue((function(e){return null==e.getAttribute("disabled")}))||de($,(function(e,t,n){var i;if(!n)return!0===e[t]?t.toLowerCase():(i=e.getAttributeNode(t))&&i.specified?i.value:null})),ae}(i);T.find=A,T.expr=A.selectors,T.expr[":"]=T.expr.pseudos,T.uniqueSort=T.unique=A.uniqueSort,T.text=A.getText,T.isXMLDoc=A.isXML,T.contains=A.contains,T.escapeSelector=A.escape;var k=function(e,t,n){for(var i=[],r=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(r&&T(e).is(n))break;i.push(e)}return i},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},O=T.expr.match.needsContext;function D(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function L(e,t,n){return v(t)?T.grep(e,(function(e,i){return!!t.call(e,i,e)!==n})):t.nodeType?T.grep(e,(function(e){return e===t!==n})):"string"!=typeof t?T.grep(e,(function(e){return u.call(t,e)>-1!==n})):T.filter(t,e,n)}T.filter=function(e,t,n){var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?T.find.matchesSelector(i,e)?[i]:[]:T.find.matches(e,T.grep(t,(function(e){return 1===e.nodeType})))},T.fn.extend({find:function(e){var t,n,i=this.length,r=this;if("string"!=typeof e)return this.pushStack(T(e).filter((function(){for(t=0;t1?T.uniqueSort(n):n},filter:function(e){return this.pushStack(L(this,e||[],!1))},not:function(e){return this.pushStack(L(this,e||[],!0))},is:function(e){return!!L(this,"string"==typeof e&&O.test(e)?T(e):e||[],!1).length}});var j,P=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(T.fn.init=function(e,t,n){var i,r;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:P.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof T?t[0]:t,T.merge(this,T.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:b,!0)),N.test(i[1])&&T.isPlainObject(t))for(i in t)v(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(r=b.getElementById(i[2]))&&(this[0]=r,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(T):T.makeArray(e,this)}).prototype=T.fn,j=T(b);var I=/^(?:parents|prev(?:Until|All))/,$={children:!0,contents:!0,next:!0,prev:!0};function H(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}T.fn.extend({has:function(e){var t=T(e,this),n=t.length;return this.filter((function(){for(var e=0;e-1:1===n.nodeType&&T.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?T.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(T(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(T.uniqueSort(T.merge(this.get(),T(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),T.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return H(e,"nextSibling")},prev:function(e){return H(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return null!=e.contentDocument&&s(e.contentDocument)?e.contentDocument:(D(e,"template")&&(e=e.content||e),T.merge([],e.childNodes))}},(function(e,t){T.fn[e]=function(n,i){var r=T.map(this,t,n);return"Until"!==e.slice(-5)&&(i=n),i&&"string"==typeof i&&(r=T.filter(i,r)),this.length>1&&($[e]||T.uniqueSort(r),I.test(e)&&r.reverse()),this.pushStack(r)}}));var q=/[^\x20\t\r\n\f]+/g;function M(e){return e}function R(e){throw e}function B(e,t,n,i){var r;try{e&&v(r=e.promise)?r.call(e).done(t).fail(n):e&&v(r=e.then)?r.call(e,t,n):t.apply(void 0,[e].slice(i))}catch(e){n.apply(void 0,[e])}}T.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return T.each(e.match(q)||[],(function(e,n){t[n]=!0})),t}(e):T.extend({},e);var t,n,i,r,o=[],s=[],a=-1,l=function(){for(r=r||e.once,i=t=!0;s.length;a=-1)for(n=s.shift();++a-1;)o.splice(n,1),n<=a&&a--})),this},has:function(e){return e?T.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return r=s=[],o=n="",this},disabled:function(){return!o},lock:function(){return r=s=[],n||t||(o=n=""),this},locked:function(){return!!r},fireWith:function(e,n){return r||(n=[e,(n=n||[]).slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!i}};return c},T.extend({Deferred:function(e){var t=[["notify","progress",T.Callbacks("memory"),T.Callbacks("memory"),2],["resolve","done",T.Callbacks("once memory"),T.Callbacks("once memory"),0,"resolved"],["reject","fail",T.Callbacks("once memory"),T.Callbacks("once memory"),1,"rejected"]],n="pending",r={state:function(){return n},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return r.then(null,e)},pipe:function(){var e=arguments;return T.Deferred((function(n){T.each(t,(function(t,i){var r=v(e[i[4]])&&e[i[4]];o[i[1]]((function(){var e=r&&r.apply(this,arguments);e&&v(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[i[0]+"With"](this,r?[e]:arguments)}))})),e=null})).promise()},then:function(e,n,r){var o=0;function s(e,t,n,r){return function(){var a=this,l=arguments,c=function(){var i,c;if(!(e=o&&(n!==R&&(a=void 0,l=[i]),t.rejectWith(a,l))}};e?u():(T.Deferred.getStackHook&&(u.stackTrace=T.Deferred.getStackHook()),i.setTimeout(u))}}return T.Deferred((function(i){t[0][3].add(s(0,i,v(r)?r:M,i.notifyWith)),t[1][3].add(s(0,i,v(e)?e:M)),t[2][3].add(s(0,i,v(n)?n:R))})).promise()},promise:function(e){return null!=e?T.extend(e,r):r}},o={};return T.each(t,(function(e,i){var s=i[2],a=i[5];r[i[1]]=s.add,a&&s.add((function(){n=a}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),s.add(i[3].fire),o[i[0]]=function(){return o[i[0]+"With"](this===o?void 0:this,arguments),this},o[i[0]+"With"]=s.fireWith})),r.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,n=t,i=Array(n),r=a.call(arguments),o=T.Deferred(),s=function(e){return function(n){i[e]=this,r[e]=arguments.length>1?a.call(arguments):n,--t||o.resolveWith(i,r)}};if(t<=1&&(B(e,o.done(s(n)).resolve,o.reject,!t),"pending"===o.state()||v(r[n]&&r[n].then)))return o.then();for(;n--;)B(r[n],s(n),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;T.Deferred.exceptionHook=function(e,t){i.console&&i.console.warn&&e&&W.test(e.name)&&i.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},T.readyException=function(e){i.setTimeout((function(){throw e}))};var F=T.Deferred();function z(){b.removeEventListener("DOMContentLoaded",z),i.removeEventListener("load",z),T.ready()}T.fn.ready=function(e){return F.then(e).catch((function(e){T.readyException(e)})),this},T.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--T.readyWait:T.isReady)||(T.isReady=!0,!0!==e&&--T.readyWait>0||F.resolveWith(b,[T]))}}),T.ready.then=F.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?i.setTimeout(T.ready):(b.addEventListener("DOMContentLoaded",z),i.addEventListener("load",z));var U=function(e,t,n,i,r,o,s){var a=0,l=e.length,c=null==n;if("object"===x(n))for(a in r=!0,n)U(e,t,a,n[a],!0,o,s);else if(void 0!==i&&(r=!0,v(i)||(s=!0),c&&(s?(t.call(e,i),t=null):(c=t,t=function(e,t,n){return c.call(T(e),n)})),t))for(;a1,null,!0)},removeData:function(e){return this.each((function(){Z.remove(this,e)}))}}),T.extend({queue:function(e,t,n){var i;if(e)return t=(t||"fx")+"queue",i=J.get(e,t),n&&(!i||Array.isArray(n)?i=J.access(e,t,T.makeArray(n)):i.push(n)),i||[]},dequeue:function(e,t){t=t||"fx";var n=T.queue(e,t),i=n.length,r=n.shift(),o=T._queueHooks(e,t);"inprogress"===r&&(r=n.shift(),i--),r&&("fx"===t&&n.unshift("inprogress"),delete o.stop,r.call(e,(function(){T.dequeue(e,t)}),o)),!i&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:T.Callbacks("once memory").add((function(){J.remove(e,[t+"queue",n])}))})}}),T.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]*)/i,ye=/^$|^module$|\/(?:java|ecma)script/i;pe=b.createDocumentFragment().appendChild(b.createElement("div")),(ge=b.createElement("input")).setAttribute("type","radio"),ge.setAttribute("checked","checked"),ge.setAttribute("name","t"),pe.appendChild(ge),m.checkClone=pe.cloneNode(!0).cloneNode(!0).lastChild.checked,pe.innerHTML="",m.noCloneChecked=!!pe.cloneNode(!0).lastChild.defaultValue,pe.innerHTML="",m.option=!!pe.lastChild;var be={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function _e(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&D(e,t)?T.merge([e],n):n}function we(e,t){for(var n=0,i=e.length;n",""]);var xe=/<|&#?\w+;/;function Ee(e,t,n,i,r){for(var o,s,a,l,c,u,d=t.createDocumentFragment(),f=[],h=0,p=e.length;h-1)r&&r.push(o);else if(c=ae(o),s=_e(d.appendChild(o),"script"),c&&we(s),n)for(u=0;o=s[u++];)ye.test(o.type||"")&&n.push(o);return d}var Te=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Ae(){return!1}function ke(e,t){return e===function(){try{return b.activeElement}catch(e){}}()==("focus"===t)}function Se(e,t,n,i,r,o){var s,a;if("object"==typeof t){for(a in"string"!=typeof n&&(i=i||n,n=void 0),t)Se(e,a,n,i,t[a],o);return e}if(null==i&&null==r?(r=n,i=n=void 0):null==r&&("string"==typeof n?(r=i,i=void 0):(r=i,i=n,n=void 0)),!1===r)r=Ae;else if(!r)return e;return 1===o&&(s=r,r=function(e){return T().off(e),s.apply(this,arguments)},r.guid=s.guid||(s.guid=T.guid++)),e.each((function(){T.event.add(this,t,r,i,n)}))}function Oe(e,t,n){n?(J.set(e,t,!1),T.event.add(e,t,{namespace:!1,handler:function(e){var i,r,o=J.get(this,t);if(1&e.isTrigger&&this[t]){if(o.length)(T.event.special[t]||{}).delegateType&&e.stopPropagation();else if(o=a.call(arguments),J.set(this,t,o),i=n(this,t),this[t](),o!==(r=J.get(this,t))||i?J.set(this,t,!1):r={},o!==r)return e.stopImmediatePropagation(),e.preventDefault(),r&&r.value}else o.length&&(J.set(this,t,{value:T.event.trigger(T.extend(o[0],T.Event.prototype),o.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===J.get(e,t)&&T.event.add(e,t,Ce)}T.event={global:{},add:function(e,t,n,i,r){var o,s,a,l,c,u,d,f,h,p,g,m=J.get(e);if(Q(e))for(n.handler&&(n=(o=n).handler,r=o.selector),r&&T.find.matchesSelector(se,r),n.guid||(n.guid=T.guid++),(l=m.events)||(l=m.events=Object.create(null)),(s=m.handle)||(s=m.handle=function(t){return void 0!==T&&T.event.triggered!==t.type?T.event.dispatch.apply(e,arguments):void 0}),c=(t=(t||"").match(q)||[""]).length;c--;)h=g=(a=Te.exec(t[c])||[])[1],p=(a[2]||"").split(".").sort(),h&&(d=T.event.special[h]||{},h=(r?d.delegateType:d.bindType)||h,d=T.event.special[h]||{},u=T.extend({type:h,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&T.expr.match.needsContext.test(r),namespace:p.join(".")},o),(f=l[h])||((f=l[h]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(e,i,p,s)||e.addEventListener&&e.addEventListener(h,s)),d.add&&(d.add.call(e,u),u.handler.guid||(u.handler.guid=n.guid)),r?f.splice(f.delegateCount++,0,u):f.push(u),T.event.global[h]=!0)},remove:function(e,t,n,i,r){var o,s,a,l,c,u,d,f,h,p,g,m=J.hasData(e)&&J.get(e);if(m&&(l=m.events)){for(c=(t=(t||"").match(q)||[""]).length;c--;)if(h=g=(a=Te.exec(t[c])||[])[1],p=(a[2]||"").split(".").sort(),h){for(d=T.event.special[h]||{},f=l[h=(i?d.delegateType:d.bindType)||h]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=f.length;o--;)u=f[o],!r&&g!==u.origType||n&&n.guid!==u.guid||a&&!a.test(u.namespace)||i&&i!==u.selector&&("**"!==i||!u.selector)||(f.splice(o,1),u.selector&&f.delegateCount--,d.remove&&d.remove.call(e,u));s&&!f.length&&(d.teardown&&!1!==d.teardown.call(e,p,m.handle)||T.removeEvent(e,h,m.handle),delete l[h])}else for(h in l)T.event.remove(e,h+t[c],n,i,!0);T.isEmptyObject(l)&&J.remove(e,"handle events")}},dispatch:function(e){var t,n,i,r,o,s,a=new Array(arguments.length),l=T.event.fix(e),c=(J.get(this,"events")||Object.create(null))[l.type]||[],u=T.event.special[l.type]||{};for(a[0]=l,t=1;t=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==e.type||!0!==c.disabled)){for(o=[],s={},n=0;n-1:T.find(r,this,null,[c]).length),s[r]&&o.push(i);o.length&&a.push({elem:c,handlers:o})}return c=this,l\s*$/g;function je(e,t){return D(e,"table")&&D(11!==t.nodeType?t:t.firstChild,"tr")&&T(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Ie(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function $e(e,t){var n,i,r,o,s,a;if(1===t.nodeType){if(J.hasData(e)&&(a=J.get(e).events))for(r in J.remove(t,"handle events"),a)for(n=0,i=a[r].length;n1&&"string"==typeof p&&!m.checkClone&&Ne.test(p))return e.each((function(r){var o=e.eq(r);g&&(t[0]=p.call(this,r,o.html())),qe(o,t,n,i)}));if(f&&(o=(r=Ee(t,e[0].ownerDocument,!1,e,i)).firstChild,1===r.childNodes.length&&(r=o),o||i)){for(a=(s=T.map(_e(r,"script"),Pe)).length;d0&&we(s,!l&&_e(e,"script")),a},cleanData:function(e){for(var t,n,i,r=T.event.special,o=0;void 0!==(n=e[o]);o++)if(Q(n)){if(t=n[J.expando]){if(t.events)for(i in t.events)r[i]?T.event.remove(n,i):T.removeEvent(n,i,t.handle);n[J.expando]=void 0}n[Z.expando]&&(n[Z.expando]=void 0)}}}),T.fn.extend({detach:function(e){return Me(this,e,!0)},remove:function(e){return Me(this,e)},text:function(e){return U(this,(function(e){return void 0===e?T.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return qe(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)}))},prepend:function(){return qe(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return qe(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return qe(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(T.cleanData(_e(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return T.clone(this,e,t)}))},html:function(e){return U(this,(function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!De.test(e)&&!be[(ve.exec(e)||["",""])[1].toLowerCase()]){e=T.htmlPrefilter(e);try{for(;n=0&&(l+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-l-a-.5))||0),l}function nt(e,t,n){var i=Be(e),r=(!m.boxSizingReliable()||n)&&"border-box"===T.css(e,"boxSizing",!1,i),o=r,s=ze(e,t,i),a="offset"+t[0].toUpperCase()+t.slice(1);if(Re.test(s)){if(!n)return s;s="auto"}return(!m.boxSizingReliable()&&r||!m.reliableTrDimensions()&&D(e,"tr")||"auto"===s||!parseFloat(s)&&"inline"===T.css(e,"display",!1,i))&&e.getClientRects().length&&(r="border-box"===T.css(e,"boxSizing",!1,i),(o=a in e)&&(s=e[a])),(s=parseFloat(s)||0)+tt(e,t,n||(r?"border":"content"),o,i,s)+"px"}function it(e,t,n,i,r){return new it.prototype.init(e,t,n,i,r)}T.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=ze(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var r,o,s,a=K(t),l=Ge.test(t),c=e.style;if(l||(t=Ke(a)),s=T.cssHooks[t]||T.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(r=s.get(e,!1,i))?r:c[t];"string"===(o=typeof n)&&(r=re.exec(n))&&r[1]&&(n=ue(e,t,r),o="number"),null!=n&&n==n&&("number"!==o||l||(n+=r&&r[3]||(T.cssNumber[a]?"":"px")),m.clearCloneStyle||""!==n||0!==t.indexOf("background")||(c[t]="inherit"),s&&"set"in s&&void 0===(n=s.set(e,n,i))||(l?c.setProperty(t,n):c[t]=n))}},css:function(e,t,n,i){var r,o,s,a=K(t);return Ge.test(t)||(t=Ke(a)),(s=T.cssHooks[t]||T.cssHooks[a])&&"get"in s&&(r=s.get(e,!0,n)),void 0===r&&(r=ze(e,t,i)),"normal"===r&&t in Ze&&(r=Ze[t]),""===n||n?(o=parseFloat(r),!0===n||isFinite(o)?o||0:r):r}}),T.each(["height","width"],(function(e,t){T.cssHooks[t]={get:function(e,n,i){if(n)return!Qe.test(T.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?nt(e,t,i):We(e,Je,(function(){return nt(e,t,i)}))},set:function(e,n,i){var r,o=Be(e),s=!m.scrollboxSize()&&"absolute"===o.position,a=(s||i)&&"border-box"===T.css(e,"boxSizing",!1,o),l=i?tt(e,t,i,a,o):0;return a&&s&&(l-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-tt(e,t,"border",!1,o)-.5)),l&&(r=re.exec(n))&&"px"!==(r[3]||"px")&&(e.style[t]=n,n=T.css(e,t)),et(0,n,l)}}})),T.cssHooks.marginLeft=Ue(m.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(ze(e,"marginLeft"))||e.getBoundingClientRect().left-We(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),T.each({margin:"",padding:"",border:"Width"},(function(e,t){T.cssHooks[e+t]={expand:function(n){for(var i=0,r={},o="string"==typeof n?n.split(" "):[n];i<4;i++)r[e+oe[i]+t]=o[i]||o[i-2]||o[0];return r}},"margin"!==e&&(T.cssHooks[e+t].set=et)})),T.fn.extend({css:function(e,t){return U(this,(function(e,t,n){var i,r,o={},s=0;if(Array.isArray(t)){for(i=Be(e),r=t.length;s1)}}),T.Tween=it,it.prototype={constructor:it,init:function(e,t,n,i,r,o){this.elem=e,this.prop=n,this.easing=r||T.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=i,this.unit=o||(T.cssNumber[n]?"":"px")},cur:function(){var e=it.propHooks[this.prop];return e&&e.get?e.get(this):it.propHooks._default.get(this)},run:function(e){var t,n=it.propHooks[this.prop];return this.options.duration?this.pos=t=T.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):it.propHooks._default.set(this),this}},it.prototype.init.prototype=it.prototype,it.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=T.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){T.fx.step[e.prop]?T.fx.step[e.prop](e):1!==e.elem.nodeType||!T.cssHooks[e.prop]&&null==e.elem.style[Ke(e.prop)]?e.elem[e.prop]=e.now:T.style(e.elem,e.prop,e.now+e.unit)}}},it.propHooks.scrollTop=it.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},T.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},T.fx=it.prototype.init,T.fx.step={};var rt,ot,st=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function lt(){ot&&(!1===b.hidden&&i.requestAnimationFrame?i.requestAnimationFrame(lt):i.setTimeout(lt,T.fx.interval),T.fx.tick())}function ct(){return i.setTimeout((function(){rt=void 0})),rt=Date.now()}function ut(e,t){var n,i=0,r={height:e};for(t=t?1:0;i<4;i+=2-t)r["margin"+(n=oe[i])]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function dt(e,t,n){for(var i,r=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,s=r.length;o1)},removeAttr:function(e){return this.each((function(){T.removeAttr(this,e)}))}}),T.extend({attr:function(e,t,n){var i,r,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?T.prop(e,t,n):(1===o&&T.isXMLDoc(e)||(r=T.attrHooks[t.toLowerCase()]||(T.expr.match.bool.test(t)?ht:void 0)),void 0!==n?null===n?void T.removeAttr(e,t):r&&"set"in r&&void 0!==(i=r.set(e,n,t))?i:(e.setAttribute(t,n+""),n):r&&"get"in r&&null!==(i=r.get(e,t))?i:null==(i=T.find.attr(e,t))?void 0:i)},attrHooks:{type:{set:function(e,t){if(!m.radioValue&&"radio"===t&&D(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,i=0,r=t&&t.match(q);if(r&&1===e.nodeType)for(;n=r[i++];)e.removeAttribute(n)}}),ht={set:function(e,t,n){return!1===t?T.removeAttr(e,n):e.setAttribute(n,n),n}},T.each(T.expr.match.bool.source.match(/\w+/g),(function(e,t){var n=pt[t]||T.find.attr;pt[t]=function(e,t,i){var r,o,s=t.toLowerCase();return i||(o=pt[s],pt[s]=r,r=null!=n(e,t,i)?s:null,pt[s]=o),r}}));var gt=/^(?:input|select|textarea|button)$/i,mt=/^(?:a|area)$/i;function vt(e){return(e.match(q)||[]).join(" ")}function yt(e){return e.getAttribute&&e.getAttribute("class")||""}function bt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(q)||[]}T.fn.extend({prop:function(e,t){return U(this,T.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[T.propFix[e]||e]}))}}),T.extend({prop:function(e,t,n){var i,r,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&T.isXMLDoc(e)||(t=T.propFix[t]||t,r=T.propHooks[t]),void 0!==n?r&&"set"in r&&void 0!==(i=r.set(e,n,t))?i:e[t]=n:r&&"get"in r&&null!==(i=r.get(e,t))?i:e[t]},propHooks:{tabIndex:{get:function(e){var t=T.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||mt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),m.optSelected||(T.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),T.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){T.propFix[this.toLowerCase()]=this})),T.fn.extend({addClass:function(e){var t,n,i,r,o,s,a,l=0;if(v(e))return this.each((function(t){T(this).addClass(e.call(this,t,yt(this)))}));if((t=bt(e)).length)for(;n=this[l++];)if(r=yt(n),i=1===n.nodeType&&" "+vt(r)+" "){for(s=0;o=t[s++];)i.indexOf(" "+o+" ")<0&&(i+=o+" ");r!==(a=vt(i))&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,i,r,o,s,a,l=0;if(v(e))return this.each((function(t){T(this).removeClass(e.call(this,t,yt(this)))}));if(!arguments.length)return this.attr("class","");if((t=bt(e)).length)for(;n=this[l++];)if(r=yt(n),i=1===n.nodeType&&" "+vt(r)+" "){for(s=0;o=t[s++];)for(;i.indexOf(" "+o+" ")>-1;)i=i.replace(" "+o+" "," ");r!==(a=vt(i))&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e,i="string"===n||Array.isArray(e);return"boolean"==typeof t&&i?t?this.addClass(e):this.removeClass(e):v(e)?this.each((function(n){T(this).toggleClass(e.call(this,n,yt(this),t),t)})):this.each((function(){var t,r,o,s;if(i)for(r=0,o=T(this),s=bt(e);t=s[r++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||((t=yt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,i=0;for(t=" "+e+" ";n=this[i++];)if(1===n.nodeType&&(" "+vt(yt(n))+" ").indexOf(t)>-1)return!0;return!1}});var _t=/\r/g;T.fn.extend({val:function(e){var t,n,i,r=this[0];return arguments.length?(i=v(e),this.each((function(n){var r;1===this.nodeType&&(null==(r=i?e.call(this,n,T(this).val()):e)?r="":"number"==typeof r?r+="":Array.isArray(r)&&(r=T.map(r,(function(e){return null==e?"":e+""}))),(t=T.valHooks[this.type]||T.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,r,"value")||(this.value=r))}))):r?(t=T.valHooks[r.type]||T.valHooks[r.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(r,"value"))?n:"string"==typeof(n=r.value)?n.replace(_t,""):null==n?"":n:void 0}}),T.extend({valHooks:{option:{get:function(e){var t=T.find.attr(e,"value");return null!=t?t:vt(T.text(e))}},select:{get:function(e){var t,n,i,r=e.options,o=e.selectedIndex,s="select-one"===e.type,a=s?null:[],l=s?o+1:r.length;for(i=o<0?l:s?o:0;i-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),T.each(["radio","checkbox"],(function(){T.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=T.inArray(T(e).val(),t)>-1}},m.checkOn||(T.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})})),m.focusin="onfocusin"in i;var wt=/^(?:focusinfocus|focusoutblur)$/,xt=function(e){e.stopPropagation()};T.extend(T.event,{trigger:function(e,t,n,r){var o,s,a,l,c,u,d,f,p=[n||b],g=h.call(e,"type")?e.type:e,m=h.call(e,"namespace")?e.namespace.split("."):[];if(s=f=a=n=n||b,3!==n.nodeType&&8!==n.nodeType&&!wt.test(g+T.event.triggered)&&(g.indexOf(".")>-1&&(m=g.split("."),g=m.shift(),m.sort()),c=g.indexOf(":")<0&&"on"+g,(e=e[T.expando]?e:new T.Event(g,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=m.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:T.makeArray(t,[e]),d=T.event.special[g]||{},r||!d.trigger||!1!==d.trigger.apply(n,t))){if(!r&&!d.noBubble&&!y(n)){for(l=d.delegateType||g,wt.test(l+g)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(n.ownerDocument||b)&&p.push(a.defaultView||a.parentWindow||i)}for(o=0;(s=p[o++])&&!e.isPropagationStopped();)f=s,e.type=o>1?l:d.bindType||g,(u=(J.get(s,"events")||Object.create(null))[e.type]&&J.get(s,"handle"))&&u.apply(s,t),(u=c&&s[c])&&u.apply&&Q(s)&&(e.result=u.apply(s,t),!1===e.result&&e.preventDefault());return e.type=g,r||e.isDefaultPrevented()||d._default&&!1!==d._default.apply(p.pop(),t)||!Q(n)||c&&v(n[g])&&!y(n)&&((a=n[c])&&(n[c]=null),T.event.triggered=g,e.isPropagationStopped()&&f.addEventListener(g,xt),n[g](),e.isPropagationStopped()&&f.removeEventListener(g,xt),T.event.triggered=void 0,a&&(n[c]=a)),e.result}},simulate:function(e,t,n){var i=T.extend(new T.Event,n,{type:e,isSimulated:!0});T.event.trigger(i,null,t)}}),T.fn.extend({trigger:function(e,t){return this.each((function(){T.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var n=this[0];if(n)return T.event.trigger(e,t,n,!0)}}),m.focusin||T.each({focus:"focusin",blur:"focusout"},(function(e,t){var n=function(e){T.event.simulate(t,e.target,T.event.fix(e))};T.event.special[t]={setup:function(){var i=this.ownerDocument||this.document||this,r=J.access(i,t);r||i.addEventListener(e,n,!0),J.access(i,t,(r||0)+1)},teardown:function(){var i=this.ownerDocument||this.document||this,r=J.access(i,t)-1;r?J.access(i,t,r):(i.removeEventListener(e,n,!0),J.remove(i,t))}}}));var Et=i.location,Tt={guid:Date.now()},Ct=/\?/;T.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new i.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||T.error("Invalid XML: "+(n?T.map(n.childNodes,(function(e){return e.textContent})).join("\n"):e)),t};var At=/\[\]$/,kt=/\r?\n/g,St=/^(?:submit|button|image|reset|file)$/i,Ot=/^(?:input|select|textarea|keygen)/i;function Dt(e,t,n,i){var r;if(Array.isArray(t))T.each(t,(function(t,r){n||At.test(e)?i(e,r):Dt(e+"["+("object"==typeof r&&null!=r?t:"")+"]",r,n,i)}));else if(n||"object"!==x(t))i(e,t);else for(r in t)Dt(e+"["+r+"]",t[r],n,i)}T.param=function(e,t){var n,i=[],r=function(e,t){var n=v(t)?t():t;i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!T.isPlainObject(e))T.each(e,(function(){r(this.name,this.value)}));else for(n in e)Dt(n,e[n],t,r);return i.join("&")},T.fn.extend({serialize:function(){return T.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=T.prop(this,"elements");return e?T.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!T(this).is(":disabled")&&Ot.test(this.nodeName)&&!St.test(e)&&(this.checked||!me.test(e))})).map((function(e,t){var n=T(this).val();return null==n?null:Array.isArray(n)?T.map(n,(function(e){return{name:t.name,value:e.replace(kt,"\r\n")}})):{name:t.name,value:n.replace(kt,"\r\n")}})).get()}});var Nt=/%20/g,Lt=/#.*$/,jt=/([?&])_=[^&]*/,Pt=/^(.*?):[ \t]*([^\r\n]*)$/gm,It=/^(?:GET|HEAD)$/,$t=/^\/\//,Ht={},qt={},Mt="*/".concat("*"),Rt=b.createElement("a");function Bt(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var i,r=0,o=t.toLowerCase().match(q)||[];if(v(n))for(;i=o[r++];)"+"===i[0]?(i=i.slice(1)||"*",(e[i]=e[i]||[]).unshift(n)):(e[i]=e[i]||[]).push(n)}}function Wt(e,t,n,i){var r={},o=e===qt;function s(a){var l;return r[a]=!0,T.each(e[a]||[],(function(e,a){var c=a(t,n,i);return"string"!=typeof c||o||r[c]?o?!(l=c):void 0:(t.dataTypes.unshift(c),s(c),!1)})),l}return s(t.dataTypes[0])||!r["*"]&&s("*")}function Ft(e,t){var n,i,r=T.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((r[n]?e:i||(i={}))[n]=t[n]);return i&&T.extend(!0,e,i),e}Rt.href=Et.href,T.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Mt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":T.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Ft(Ft(e,T.ajaxSettings),t):Ft(T.ajaxSettings,e)},ajaxPrefilter:Bt(Ht),ajaxTransport:Bt(qt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var n,r,o,s,a,l,c,u,d,f,h=T.ajaxSetup({},t),p=h.context||h,g=h.context&&(p.nodeType||p.jquery)?T(p):T.event,m=T.Deferred(),v=T.Callbacks("once memory"),y=h.statusCode||{},_={},w={},x="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s)for(s={};t=Pt.exec(o);)s[t[1].toLowerCase()+" "]=(s[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=s[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return c?o:null},setRequestHeader:function(e,t){return null==c&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,_[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)y[t]=[y[t],e[t]];return this},abort:function(e){var t=e||x;return n&&n.abort(t),C(0,t),this}};if(m.promise(E),h.url=((e||h.url||Et.href)+"").replace($t,Et.protocol+"//"),h.type=t.method||t.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(q)||[""],null==h.crossDomain){l=b.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Rt.protocol+"//"+Rt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=T.param(h.data,h.traditional)),Wt(Ht,h,t,E),c)return E;for(d in(u=T.event&&h.global)&&0==T.active++&&T.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!It.test(h.type),r=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Nt,"+")):(f=h.url.slice(r.length),h.data&&(h.processData||"string"==typeof h.data)&&(r+=(Ct.test(r)?"&":"?")+h.data,delete h.data),!1===h.cache&&(r=r.replace(jt,"$1"),f=(Ct.test(r)?"&":"?")+"_="+Tt.guid+++f),h.url=r+f),h.ifModified&&(T.lastModified[r]&&E.setRequestHeader("If-Modified-Since",T.lastModified[r]),T.etag[r]&&E.setRequestHeader("If-None-Match",T.etag[r])),(h.data&&h.hasContent&&!1!==h.contentType||t.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Mt+"; q=0.01":""):h.accepts["*"]),h.headers)E.setRequestHeader(d,h.headers[d]);if(h.beforeSend&&(!1===h.beforeSend.call(p,E,h)||c))return E.abort();if(x="abort",v.add(h.complete),E.done(h.success),E.fail(h.error),n=Wt(qt,h,t,E)){if(E.readyState=1,u&&g.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(a=i.setTimeout((function(){E.abort("timeout")}),h.timeout));try{c=!1,n.send(_,C)}catch(e){if(c)throw e;C(-1,e)}}else C(-1,"No Transport");function C(e,t,s,l){var d,f,b,_,w,x=t;c||(c=!0,a&&i.clearTimeout(a),n=void 0,o=l||"",E.readyState=e>0?4:0,d=e>=200&&e<300||304===e,s&&(_=function(e,t,n){for(var i,r,o,s,a=e.contents,l=e.dataTypes;"*"===l[0];)l.shift(),void 0===i&&(i=e.mimeType||t.getResponseHeader("Content-Type"));if(i)for(r in a)if(a[r]&&a[r].test(i)){l.unshift(r);break}if(l[0]in n)o=l[0];else{for(r in n){if(!l[0]||e.converters[r+" "+l[0]]){o=r;break}s||(s=r)}o=o||s}if(o)return o!==l[0]&&l.unshift(o),n[o]}(h,E,s)),!d&&T.inArray("script",h.dataTypes)>-1&&T.inArray("json",h.dataTypes)<0&&(h.converters["text script"]=function(){}),_=function(e,t,n,i){var r,o,s,a,l,c={},u=e.dataTypes.slice();if(u[1])for(s in e.converters)c[s.toLowerCase()]=e.converters[s];for(o=u.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&i&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=u.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(!(s=c[l+" "+o]||c["* "+o]))for(r in c)if((a=r.split(" "))[1]===o&&(s=c[l+" "+a[0]]||c["* "+a[0]])){!0===s?s=c[r]:!0!==c[r]&&(o=a[0],u.unshift(a[1]));break}if(!0!==s)if(s&&e.throws)t=s(t);else try{t=s(t)}catch(e){return{state:"parsererror",error:s?e:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}(h,_,E,d),d?(h.ifModified&&((w=E.getResponseHeader("Last-Modified"))&&(T.lastModified[r]=w),(w=E.getResponseHeader("etag"))&&(T.etag[r]=w)),204===e||"HEAD"===h.type?x="nocontent":304===e?x="notmodified":(x=_.state,f=_.data,d=!(b=_.error))):(b=x,!e&&x||(x="error",e<0&&(e=0))),E.status=e,E.statusText=(t||x)+"",d?m.resolveWith(p,[f,x,E]):m.rejectWith(p,[E,x,b]),E.statusCode(y),y=void 0,u&&g.trigger(d?"ajaxSuccess":"ajaxError",[E,h,d?f:b]),v.fireWith(p,[E,x]),u&&(g.trigger("ajaxComplete",[E,h]),--T.active||T.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return T.get(e,t,n,"json")},getScript:function(e,t){return T.get(e,void 0,t,"script")}}),T.each(["get","post"],(function(e,t){T[t]=function(e,n,i,r){return v(n)&&(r=r||i,i=n,n=void 0),T.ajax(T.extend({url:e,type:t,dataType:r,data:n,success:i},T.isPlainObject(e)&&e))}})),T.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),T._evalUrl=function(e,t,n){return T.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){T.globalEval(e,t,n)}})},T.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=T(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return v(e)?this.each((function(t){T(this).wrapInner(e.call(this,t))})):this.each((function(){var t=T(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)}))},wrap:function(e){var t=v(e);return this.each((function(n){T(this).wrapAll(t?e.call(this,n):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){T(this).replaceWith(this.childNodes)})),this}}),T.expr.pseudos.hidden=function(e){return!T.expr.pseudos.visible(e)},T.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},T.ajaxSettings.xhr=function(){try{return new i.XMLHttpRequest}catch(e){}};var zt={0:200,1223:204},Ut=T.ajaxSettings.xhr();m.cors=!!Ut&&"withCredentials"in Ut,m.ajax=Ut=!!Ut,T.ajaxTransport((function(e){var t,n;if(m.cors||Ut&&!e.crossDomain)return{send:function(r,o){var s,a=e.xhr();if(a.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(s in e.xhrFields)a[s]=e.xhrFields[s];for(s in e.mimeType&&a.overrideMimeType&&a.overrideMimeType(e.mimeType),e.crossDomain||r["X-Requested-With"]||(r["X-Requested-With"]="XMLHttpRequest"),r)a.setRequestHeader(s,r[s]);t=function(e){return function(){t&&(t=n=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(zt[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=t(),n=a.onerror=a.ontimeout=t("error"),void 0!==a.onabort?a.onabort=n:a.onreadystatechange=function(){4===a.readyState&&i.setTimeout((function(){t&&n()}))},t=t("abort");try{a.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}})),T.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),T.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return T.globalEval(e),e}}}),T.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),T.ajaxTransport("script",(function(e){var t,n;if(e.crossDomain||e.scriptAttrs)return{send:function(i,r){t=T("