From 373118365462d65ff3dd49594e37fd218b329a0c Mon Sep 17 00:00:00 2001 From: Fabio Herzig Date: Sat, 18 Apr 2026 23:45:17 +0200 Subject: [PATCH] =?UTF-8?q?=C3=9Cberarbeitete=20Version=20der=201.=20Versi?= =?UTF-8?q?on.=20Es=20bestehen=20noch=20grosse=20Feher=20in=20einzelnen=20?= =?UTF-8?q?Skripten.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + scripts/csrf_functions.php | 16 - scripts/db/db-verbindung-script-guest.php | 18 - scripts/db/db-verbindung-script.php | 21 +- scripts/kampfrichter/check-user-freigaben.php | 8 +- scripts/kampfrichter/post-handler.php | 303 +--------- scripts/login/login.php | 15 +- scripts/session_functions.php | 104 ++++ .../string-calculator-functions.php | 124 +++- scripts/trainer/post-handler.php | 264 ++++----- www/displays/display.php | 2 - www/intern/css/einstellungen.css | 258 ++++++-- www/intern/css/kampfrichter.css | 26 +- www/intern/css/logindata.css | 58 +- www/intern/css/otl.css | 120 ++++ www/intern/css/sidebar.css | 40 +- www/intern/img/icon.png | Bin 54705 -> 9871 bytes www/intern/js/sidebar.js | 3 +- www/intern/kampfrichter.php | 396 +++++++++---- www/intern/otlogin.php | 551 ++++++++++-------- www/intern/scripts/abt_handler.php | 94 --- www/intern/scripts/ajax-create-ws-token.php | 21 +- ....php => ajax-update_selected_freigabe.php} | 26 +- .../ajax_audiofile_upload.php | 23 +- .../db/migrations/multi_run_support.sql | 10 - .../ajax-update_display_config_json.php | 13 +- www/intern/scripts/einstellungen/.user.ini | 4 + .../einstellungen/ajax-change-value.php | 15 +- .../einstellungen/ajax-gereate-management.php | 19 +- .../einstellungen/ajax-noten-management.php | 21 +- .../einstellungen/ajax-upload-image.php | 15 +- .../ajax/ajax-kampfrichter_currentedit.php | 55 +- .../kampfrichter/ajax/ajax-neu_protokoll.php | 18 +- .../kampfrichter/ajax/ajax-neu_rangliste.php | 25 +- .../ajax-update_kampfrichter_start_musik.php | 24 +- .../ajax-update_kampfrichter_stopp_musik.php | 10 +- ...jax-update_name_kampfrichter_protokoll.php | 21 +- .../ajax/ajax-update_value_kampfrichter.php | 182 ++++-- .../ajax-update_value_kampfrichter_admin.php | 93 --- .../ajax/displays/ajax-display-functions.php | 43 +- ...ax-update_write_discipline_json_result.php | 115 ---- ...jax-update_write_discipline_json_start.php | 97 --- ...-update_write_discipline_json_turnerin.php | 122 ---- .../scripts/kampfrichter/ajax/neu copy.php | 160 ----- www/intern/scripts/kampfrichter/ajax/neu.php | 2 +- .../kampfrichter/js/js-kampfrichter-normal.js | 510 +++++++--------- .../logindata/ajax-create-link-user.php | 167 ++++++ .../{ajax05.php => ajax-create-otl.php} | 32 +- .../scripts/logindata/ajax-delete-user.php | 39 ++ .../scripts/logindata/ajax-delete-verein.php | 36 ++ .../scripts/logindata/ajax-neu_programm.php | 24 +- .../logindata/ajax-remove_programm.php | 24 +- .../ajax-update-user-information.php | 35 +- .../logindata/ajax-update_programm_aktiv.php | 27 +- .../logindata/ajax-update_programm_preis.php | 27 +- .../logindata/ajax-vereine-handler.php | 18 +- www/intern/scripts/logindata/ajax02.php | 46 -- www/intern/scripts/logindata/ajax04.php | 36 -- .../scripts/rechnungen/ajax_delete_order.php | 15 +- .../rechnungen/ajax_update_order_status.php | 15 +- .../ajax_auto_riegeneinteilung.php | 17 +- .../ajax_change_number_of_abt.php | 19 +- .../ajax_delete_specific_abt.php | 19 +- .../ajax_update_start_indexes.php | 21 +- .../riegeneinteilung/ajax_update_turnerin.php | 17 +- www/intern/scripts/sidebar/sidebar.php | 10 +- .../trainer/ajax-add_entry_fees_to_basket.php | 19 +- .../scripts/trainer/ajax-create_otlurl.php | 0 .../scripts/trainer/ajax-fetch_temp_order.php | 23 +- .../scripts/trainer/ajax-neu_temp_order.php | 22 +- .../trainer/ajax-remove_basket_item.php | 19 +- .../scripts/trainer/ajax_link_bodenmusik.php | 19 +- .../trainer/ajax_unlink_delete_bodenmusik.php | 19 +- .../trainer/rechnung/ajax-neu_qr_rechnung.php | 2 +- .../scripts/trainer/rechnung/rechnung-pdf.php | 24 +- www/intern/trainer.php | 153 ++--- www/intern/wk-leitung/displaycontrol.php | 24 +- www/intern/wk-leitung/einstellungen.php | 208 ++++--- www/intern/wk-leitung/index.php | 10 +- www/intern/wk-leitung/kalender.php | 529 ----------------- www/intern/wk-leitung/logindata.php | 404 ++++++++++--- www/intern/wk-leitung/rechnungen.php | 21 +- www/intern/wk-leitung/rechnungen_viewer.php | 14 +- www/intern/wk-leitung/riegeneinteilung.php | 41 +- www/liveScoring/index.php | 74 +++ 85 files changed, 2965 insertions(+), 3371 deletions(-) delete mode 100644 scripts/csrf_functions.php create mode 100644 scripts/session_functions.php create mode 100644 www/intern/css/otl.css delete mode 100644 www/intern/scripts/abt_handler.php rename www/intern/scripts/{kampfrichter/ajax/ajax-update_selected_kampfrichter.php => ajax-update_selected_freigabe.php} (56%) delete mode 100644 www/intern/scripts/db/migrations/multi_run_support.sql create mode 100644 www/intern/scripts/einstellungen/.user.ini delete mode 100644 www/intern/scripts/kampfrichter/ajax/ajax-update_value_kampfrichter_admin.php delete mode 100644 www/intern/scripts/kampfrichter/ajax/displays/ajax-update_write_discipline_json_result.php delete mode 100644 www/intern/scripts/kampfrichter/ajax/displays/ajax-update_write_discipline_json_start.php delete mode 100644 www/intern/scripts/kampfrichter/ajax/displays/ajax-update_write_discipline_json_turnerin.php delete mode 100644 www/intern/scripts/kampfrichter/ajax/neu copy.php create mode 100644 www/intern/scripts/logindata/ajax-create-link-user.php rename www/intern/scripts/logindata/{ajax05.php => ajax-create-otl.php} (69%) create mode 100644 www/intern/scripts/logindata/ajax-delete-user.php create mode 100644 www/intern/scripts/logindata/ajax-delete-verein.php delete mode 100644 www/intern/scripts/logindata/ajax02.php delete mode 100644 www/intern/scripts/logindata/ajax04.php delete mode 100644 www/intern/scripts/trainer/ajax-create_otlurl.php delete mode 100644 www/intern/wk-leitung/kalender.php create mode 100644 www/liveScoring/index.php diff --git a/.gitignore b/.gitignore index 2629c29..7ae91e8 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ private-files/rechnungen/* .php-ini .php-version www/displays/json/* +www/intern/scripts/kampfrichter/ajax/neu.php +www/intern/scripts/kampfrichter/ajax/neu_copy.php \ No newline at end of file diff --git a/scripts/csrf_functions.php b/scripts/csrf_functions.php deleted file mode 100644 index 7b39431..0000000 --- a/scripts/csrf_functions.php +++ /dev/null @@ -1,16 +0,0 @@ - false, - 'message' => 'security check failed: ERROR 01' - ]); - exit; -} - -if ($token !== 'QQa2UMbEYW8oOL7wz9DjtqECVCikSZsDuSdmzxiadEXFsKyujEUyQOW1AYMD2OqU8VXxClIRweRuWLzvBrZpPYL41e89Rs96tM7Lq1KpjA5E2mg2UfgvztheGRV'){ - http_response_code(403); - echo json_encode([ - 'success' => false, - 'message' => 'security check failed: ERROR 02' - ]); - exit; -} - require __DIR__ . '/../../composer/vendor/autoload.php'; $envFile = realpath(__DIR__ . '/../../config/.env.db-guest'); diff --git a/scripts/db/db-verbindung-script.php b/scripts/db/db-verbindung-script.php index 6e214e3..c97eb3e 100644 --- a/scripts/db/db-verbindung-script.php +++ b/scripts/db/db-verbindung-script.php @@ -2,7 +2,9 @@ use Dotenv\Dotenv; -if(session_status() !== PHP_SESSION_ACTIVE) session_start(); +require_once __DIR__ . '/../session_functions.php'; + +ini_wkvs_session(); if (!isset($type)){ return [ @@ -12,22 +14,13 @@ if (!isset($type)){ } if ($type === 'kr'){ - if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) { - http_response_code(403); - exit; - } + check_user_permission('kampfrichter'); } elseif ($type === 'tr'){ - if (empty($_SESSION['access_granted_trainer']) || $_SESSION['access_granted_trainer'] !== true || empty($_SESSION['passcodetrainer_id']) || $_SESSION['passcodetrainer_id'] < 1) { - http_response_code(403); - exit; - } + check_user_permission('trainer'); } elseif ($type === 'wkl') { - if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) { - http_response_code(403); - exit; - } + check_user_permission('wk_leitung'); } elseif ($type === 'otl') { - if (empty($_SESSION['set_new_password_id_user']) || empty($_SESSION['set_new_password_granted']) || $_SESSION['set_new_password_granted'] !== true || $_SESSION['set_new_password_id_user'] < 1 ) { + if (empty($_SESSION['access_granted_db_otl']) || $_SESSION['access_granted_db_otl'] !== true) { http_response_code(403); exit; } diff --git a/scripts/kampfrichter/check-user-freigaben.php b/scripts/kampfrichter/check-user-freigaben.php index 7cb7b59..ac2129d 100644 --- a/scripts/kampfrichter/check-user-freigaben.php +++ b/scripts/kampfrichter/check-user-freigaben.php @@ -1,12 +1,6 @@ 0) { diff --git a/scripts/kampfrichter/post-handler.php b/scripts/kampfrichter/post-handler.php index cb115ce..a217ea7 100644 --- a/scripts/kampfrichter/post-handler.php +++ b/scripts/kampfrichter/post-handler.php @@ -1,277 +1,11 @@ "`note $d`", $disciplines)); - - $columns_array = array_merge( - ['id', 'programm'], - array_map(fn($d) => "note $d", $disciplines) - ); - - - $all_rows = db_select($mysqli, $tableTurnerinnen, $columns_array, 'bezahlt = ? OR bezahltoverride = ?', ['2', '5']); - - - $success = 0; - // Step 1: Calculate gesamtpunktzahl and update per row - foreach ($all_rows as $row) { - $sum = 0; - foreach ($disciplines as $discipline) { - $value = $row["note $discipline"]; - if (is_numeric($value)) { - $sum += floatval($value); - } - } - db_update($mysqli, $tableTurnerinnen, ['gesamtpunktzahl' => $sum], ['id' => $row['id']]); - $success++; - } - - // Step 2: Re-fetch rows grouped by programm with updated gesamtpunktzahl - - $all_programms = db_get_col($mysqli, "SELECT DISTINCT programm FROM ".$tableTurnerinnen); - foreach ($all_programms as $programm) { - $group = db_select($mysqli, $tableTurnerinnen, ['id', 'gesamtpunktzahl', 'note sprung', 'note barren', 'note balken', 'note boden', 'geburtsdatum'], 'programm = ? AND (bezahlt = ? OR bezahltoverride = ?)', [$programm, '2', '5']); - - usort($group, function ($a, $b) { - $scoreA = floatval($a['gesamtpunktzahl']); - $scoreB = floatval($b['gesamtpunktzahl']); - - if ($scoreA !== $scoreB) return $scoreB <=> $scoreA; - - // Only for top 3 tie-breaking - $scoresA = [ - floatval($a['note sprung']), - floatval($a['note barren']), - floatval($a['note balken']), - floatval($a['note boden']), - ]; - $scoresB = [ - floatval($b['note sprung']), - floatval($b['note barren']), - floatval($b['note balken']), - floatval($b['note boden']), - ]; - - rsort($scoresA); - rsort($scoresB); - - $sumTop3A = $scoresA[0] + $scoresA[1] + $scoresA[2]; - $sumTop3B = $scoresB[0] + $scoresB[1] + $scoresB[2]; - if (abs($sumTop3A - $sumTop3B) > 0.001) return $sumTop3B <=> $sumTop3A; - - $sumTop2A = $scoresA[0] + $scoresA[1]; - $sumTop2B = $scoresB[0] + $scoresB[1]; - if (abs($sumTop2A - $sumTop2B) > 0.001) return $sumTop2B <=> $sumTop2A; - - if (abs($scoresA[0] - $scoresB[0]) > 0.001) return $scoresB[0] <=> $scoresA[0]; - - // Younger participant ranks higher in case of full tie - $dateA = strtotime($a['geburtsdatum']); - $dateB = strtotime($b['geburtsdatum']); - return $dateB <=> $dateA; // later birthdate = younger = better - }); - - // Step 2: Assign ranks - $ranked = []; - $current_rank = 1; - $i = 0; - - while ($i < count($group)) { - $current = $group[$i]; - $tie_group = [$current]; - $j = $i + 1; - - while ($j < count($group)) { - $next = $group[$j]; - - // Tie logic - if ($current_rank <= 3) { - // Top 3: full tie-breaking - $is_tie = - round(floatval($current['gesamtpunktzahl']), 3) === round(floatval($next['gesamtpunktzahl']), 3) && - round(floatval($current['note sprung']), 3) === round(floatval($next['note sprung']), 3) && - round(floatval($current['note barren']), 3) === round(floatval($next['note barren']), 3) && - round(floatval($current['note balken']), 3) === round(floatval($next['note balken']), 3) && - round(floatval($current['note boden']), 3) === round(floatval($next['note boden']), 3) && - $current['geburtsdatum'] === $next['geburtsdatum']; - } else { - // Ranks > 3: only check gesamtpunktzahl - $is_tie = round(floatval($current['gesamtpunktzahl']), 3) === round(floatval($next['gesamtpunktzahl']), 3); - } - - if ($is_tie) { - $tie_group[] = $next; - $j++; - } else { - break; - } - } - - // Assign the same rank for all ties in ranks > 3 - foreach ($tie_group as $entry) { - $ranked[] = [ - 'id' => $entry['id'], - 'rang' => $current_rank - ]; - } - - $i += count($tie_group); - $current_rank += count($tie_group); - } - - // Step 3: Write all ranks to DB - foreach ($ranked as $r) { - db_update($mysqli, $tableTurnerinnen, ['rang' => $r['rang']], ['id' => $r['id']]); - } - } - - - $_SESSION['form_message'] = - $success . ' Einträge wurden aktualisiert und neu gerankt.'; - header("Location: ". $_SERVER['REQUEST_URI']); - exit; -} -} - -if ($selecteduser === 'admin' && isset($_POST['reset_scores'])) { -if (!verify_csrf()) { - $form_message = 'Sicherheitsproblem bei der Neuberechnung.'; -} else { - $all_rows = db_select($mysqli, $tableTurnerinnen, 'id'); - $success = 0; - foreach ($all_rows as $row) { - db_update($mysqli, $tableTurnerinnen, ['gesamtpunktzahl' => 0, 'rang' => 0], ['id' => $row['id']]); - $success++; - } - - $_SESSION['form_message'] = '
' . $success . ' Einträge wurden zurückgesetzt.
'; - header("Location: ". $_SERVER['REQUEST_URI']); - exit; -} -} - - -// === EDIT MODE: Load existing data if edit_id is present in URL === -$edit_row = null; -if (isset($_GET['edit_id']) && is_numeric($_GET['edit_id']) && !isset($_POST['submit_turnerinnen_form'])) { - $edit_id = intval($_GET['edit_id']); - - $edit_row = db_select($mysqli, $tableTurnerinnen, '*', 'id = ?', [$edit_id]); - - foreach ($disciplines as $discipline) { - if ($selecteduser === ucfirst($discipline) || $selecteduser === 'admin') { - $_POST["d-note_{$discipline}"] = $edit_row["d-note {$discipline}"] ?? - ''; - $_POST["note_{$discipline}"] = $edit_row["note {$discipline}"] ?? ''; - } - } - if ($selecteduser === 'admin') { - $gesamt = 0; - foreach ($disciplines as $discipline) { - if (isset($edit_row[0]["note {$discipline}"]) && is_numeric($edit_row[0]["note {$discipline}"])) { - $gesamt += floatval($edit_row[0]["note {$discipline}"]); - } - } - $_POST["gesamtpunktzahl"] = $gesamt; - $rang = isset($_POST['rang']) ? intval($_POST['rang']) : 0; // Safely get and cast to int - $data_to_insert["rang"] = $rang; - $data_formats[] = '%d'; - } - - $_POST['edit_id'] = $edit_id; -} - -if (isset($_POST['submit_turnerinnen_form'])) { - // Check nonce - if (!verify_csrf()) { - $form_message = 'Sicherheitsproblem: Ungültige Formularübermittlung.'; - } else { - - - foreach ($disciplines as $discipline) { - if ($selecteduser === ucfirst($discipline) || $selecteduser === 'admin') { - ${"d_note_$discipline"} = floatval($_POST["d-note_{$discipline}"]); - ${"note_$discipline"} = floatval($_POST["note_{$discipline}"]); - - // Add to data array - $data_to_insert["d-note $discipline"] = ${"d_note_$discipline"}; - $data_to_insert["note $discipline"] = ${"note_$discipline"}; - - $data_formats[] = '%f'; // float format for d-note - $data_formats[] = '%f'; - // float format for note - } - } - - if ($selecteduser === 'admin') { - $gesamtpunktzahl = isset($_POST['gesamtpunktzahl']) ? - intval($_POST['gesamtpunktzahl']) : 0; // Safely get and cast to int - $data_to_insert["gesamtpunktzahl"] = $gesamtpunktzahl; - $data_formats[] = '%f'; - // CORRECTED LINE: Get 'rang' from $_POST - $rang = isset($_POST['rang']) ? - intval($_POST['rang']) : 0; // Safely get and cast to int - $data_to_insert["rang"] = $rang; - $data_formats[] = '%d'; - } - - - - - - - // Check if we are editing an existing entry - $is_editing = isset($_POST['edit_id']) && is_numeric($_POST['edit_id']) && $_POST['edit_id'] > 0; - if ($is_editing) { - $edit_id = intval($_POST['edit_id']); - $updated = db_update($mysqli, $tableTurnerinnen, $data_to_insert, ['id' => $edit_id]); - if ($updated === false) { - $form_message = 'Fehler beim Aktualisieren des Eintrags.'; - } else if ($updated === 0) { - $form_message = 'Keine Änderungen vorgenommen.'; - } else { - $_SESSION['form_message'] = 'Eintrag erfolgreich aktualisiert!'; - $_POST = []; - - $parsed = parse_url($_SERVER['REQUEST_URI']); - - if (!isset($parsed['query'])) { - return $url; - } - - parse_str($parsed['query'], $query); - - unset($query[$param]); // remove the parameter - - $base = $parsed['path'] ?? ''; - $new_query = http_build_query($query); - - $url = $new_query ? $base . '?' . $new_query : $base; - - header("Location: ". $url); - - exit; - } - } - } -} - if ((isset($_POST['prev_abt'])) && !empty($_POST['prev_abt_submit'])) { + verify_csrf(); $value = $aktabt; if ($value > 1){ $value -= 1; @@ -285,10 +19,11 @@ if ((isset($_POST['prev_abt'])) && !empty($_POST['prev_abt_submit'])) { $stmt->close(); } header("Location: /intern/kampfrichter"); -exit; + exit; } if ((isset($_POST['next_abt'])) && !empty($_POST['next_abt_submit'])) { + verify_csrf(); $value = $aktabt; $maxvalue = db_get_var($mysqli, "SELECT name FROM $tableAbt ORDER BY name DESC LIMIT 1"); @@ -322,6 +57,7 @@ if ($_SESSION['last_abt'] !== $aktabt){ } if ((isset($_POST['prev_subabt'])) && !empty($_POST['prev_subabt_submit'])) { + verify_csrf(); $value = $_SESSION['currentsubabt']; if ($value > 1){ $_SESSION['currentsubabt']--; @@ -333,6 +69,7 @@ if ((isset($_POST['prev_subabt'])) && !empty($_POST['prev_subabt_submit'])) { } if ((isset($_POST['next_subabt'])) && !empty($_POST['next_subabt_submit'])) { + verify_csrf(); $value = $_SESSION['currentsubabt']; if ($value < $maxsubabt){ $_SESSION['currentsubabt']++; @@ -343,7 +80,8 @@ if ((isset($_POST['next_subabt'])) && !empty($_POST['next_subabt_submit'])) { exit; } -if ( isset($_POST['togle_advanced_mode_admin']) && !empty($_POST['togle_advanced_mode_admin_submit']) ) { +if ( isset($_POST['togle_advanced_mode_admin']) && !empty($_POST['togle_advanced_mode_admin_submit']) && !empty($_POST['csrf_token'])) { + verify_csrf(); $current_value = $focus_view_admin; $new_value = !$current_value; @@ -351,31 +89,4 @@ if ( isset($_POST['togle_advanced_mode_admin']) && !empty($_POST['togle_advanced header("Location: /intern/kampfrichter"); exit; -} - -if ((isset($_POST['upload_remove_pdf_for_programm'])) && !empty($_POST['programm_remove_export'])) { - - $current_year = date('Y'); - $monat = date('n'); - if ($monat > 6) $current_year++; - - $programm = trim($_POST['programm_remove_export']); - - $dir = $_SERVER['DOCUMENT_ROOT'] . '/wp-content/ergebnisse'; - if (!file_exists($dir)) { - mkdir($dir, 0755, true); - } - $localPath = $_SERVER['DOCUMENT_ROOT'] . "/wp-content/ergebnisse/KTBB_Ergebnisse_" . $programm . "_" . $current_year . ".pdf"; - - // --- ADDED CODE START --- - // Check if the file already exists and delete it - if (file_exists($localPath)) { - unlink($localPath); - } - // --- ADDED CODE END --- - - $_SESSION['form_message'] = 'PDF wurde gelöscht'; - - - header("Location: ". $_SERVER['REQUEST_URI']); } \ No newline at end of file diff --git a/scripts/login/login.php b/scripts/login/login.php index eaec7b7..4762c34 100644 --- a/scripts/login/login.php +++ b/scripts/login/login.php @@ -1,8 +1,8 @@ time()) { $error = "Zu viele fehlgeschlagene Anmeldeversuche. Bitte warte $minutes Minute(n)."; } elseif (isset($_POST[$logintype.'_login_submit'])) { - $token = "QQa2UMbEYW8oOL7wz9DjtqECVCikSZsDuSdmzxiadEXFsKyujEUyQOW1AYMD2OqU8VXxClIRweRuWLzvBrZpPYL41e89Rs96tM7Lq1KpjA5E2mg2UfgvztheGRV"; - require __DIR__ .'/../db/db-verbindung-script-guest.php'; require __DIR__ . "/../db/db-tables.php"; @@ -35,8 +33,9 @@ if ($_SESSION['lockout_time_'. $logintype] > time()) { $password = trim($_POST['access_passcode']); // Prepare statement - $stmt = $guest->prepare("SELECT * FROM $tableInternUsers WHERE username = ? LIMIT 1"); - $stmt->bind_param("s", $username); + $stmt = $guest->prepare("SELECT * FROM $tableInternUsers WHERE username = ? AND login_active = ? LIMIT 1"); + $loginActive = 1; + $stmt->bind_param("ss", $username, $loginActive); $stmt->execute(); $result = $stmt->get_result(); $user = $result->fetch_assoc(); @@ -60,7 +59,7 @@ if ($_SESSION['lockout_time_'. $logintype] > time()) { if (password_verify($password, $user['password_hash']) && in_array($logintype, $freigabe_values)) { foreach ($freigabe_values as $freigabe) { $_SESSION['access_granted_'. $freigabe] = true; - $_SESSION['passcode'. $freigabe .'_id'] = $user['id']; + $_SESSION['user_id_'. $freigabe] = $user['id']; $_SESSION['lockout_time_'. $freigabe] = 0; $_SESSION['login_attempts_'. $freigabe] = 0; } diff --git a/scripts/session_functions.php b/scripts/session_functions.php new file mode 100644 index 0000000..0bfaa47 --- /dev/null +++ b/scripts/session_functions.php @@ -0,0 +1,104 @@ + 0, + 'path' => '/', + 'domain' => '', + 'secure' => true, + 'httponly' => true, + 'samesite' => 'Lax', + ]); + + + session_start(); + } + + if ($regenerate) { + session_regenerate_id(true); + } + if ($set_csrf && !isset($_SESSION['csrf_token'])) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(64)); + } +} + +function verify_csrf() { + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $token = $_POST['csrf_token'] ?? ''; + if (!hash_equals($_SESSION['csrf_token'], $token)) { + http_response_code(403); + die("Access Denied: Invalid CSRF Token."); + } + } else { + http_response_code(403); + die("Access Denied: Invalid Request Type."); + } +} + +$allowedUserTypes = ['trainer', 'kampfrichter', 'wk_leitung']; + +function check_user_permission(string $type, bool $return = false) { + global $allowedUserTypes; + + if (!in_array($type, $allowedUserTypes, true)) { + if ($return) { + return false; + } else { + http_response_code(403); + die("Invalid User Type Configuration"); + } + } + + $accessKey = "access_granted_{$type}"; + $idKey = "user_id_{$type}"; + + $hasAccess = ($_SESSION[$accessKey] ?? false) === true; + $hasValidId = isset($_SESSION[$idKey]) && intval($_SESSION[$idKey]) > 0; + + if (!$hasAccess || !$hasValidId) { + if ($return) { + return false; + } else { + http_response_code(403); + die("Access Denied"); + } + } + + if ($return) { + return true; + } +} + +function check_multiple_allowed_permissions(array $types) { + $authorized = false; + + foreach ($types as $type) { + if (check_user_permission($type, true)) { + $authorized = true; + break; + } + } + + if (!$authorized) { + http_response_code(403); + die("Access Denied"); + } +} \ No newline at end of file diff --git a/scripts/string-calculator/string-calculator-functions.php b/scripts/string-calculator/string-calculator-functions.php index 06a7044..1fefaf4 100644 --- a/scripts/string-calculator/string-calculator-functions.php +++ b/scripts/string-calculator/string-calculator-functions.php @@ -13,9 +13,14 @@ use ChrisKonnertz\StringCalc\StringCalc; class NotenRechner { + private $Rfunctions = ["MAXR", "MINR", "AVGR", "SUMR"]; + private $RfunctionsSan = []; + public function __construct( private StringCalc $rechner = new StringCalc() - ) {} + ) { + $this->RfunctionsSan = implode('|', array_map('preg_quote', $this->Rfunctions)); + } /* Es wird ein Array mit allen Notentypen pro Gerät, Jahr und Person erwartet, so dass noten_bezeichnung_id als Key verwendet werden kann: @@ -95,7 +100,7 @@ class NotenRechner { } } - private function insertValuesComplex(string $schemaRaw, array $valuesArray, int $currentId) + private function insertValuesComplex(string $schemaRaw, array $valuesArray, int $currentId, int $runNumber) { $schema = $this->santinzeString($schemaRaw); $idsNeededArray = $this->getBenoetigteIdsComplex($schemaRaw); @@ -104,7 +109,6 @@ class NotenRechner { foreach ($idsNeededArray as $sina) { $noteId = $sina['noteId']; $geraetIdSearch = ($sina['geraetId'] === 'A') ? $currentId : $sina['geraetId']; - $runNumber = $sina['run'] ?? 1; if (!isset($valuesArray[$geraetIdSearch][$noteId][$runNumber])) { return ['success' => false, 'value' => "Fehlende Daten für Gerät $geraetIdSearch, Note $noteId, Lauf $runNumber"]; @@ -112,15 +116,13 @@ class NotenRechner { } try { - $returnStr = preg_replace_callback('/\{(\d+)(?:\[(\w*)\])?(?:\[(\d+)\])?\}/', function($m) use ($valuesArray, $currentId) { + $returnStr = preg_replace_callback('/\{(\d+)(?:\[(\w*)\])?(?:\[(\d+)\])?\}/', function($m) use ($valuesArray, $currentId, $runNumber) { $noteId = $m[1]; // Get value inside brackets, default to 'S' if none exists $rawGeraet = $m[2] ?? 'S'; $geraetId = ($rawGeraet === 'S' || $rawGeraet === '') ? $currentId : $rawGeraet; - $runNumber = isset($m[3]) ? (int)$m[3] : 1; - // Return value from [Device][Note][Run] return $valuesArray[$geraetId][$noteId][$runNumber] ?? 0; @@ -160,16 +162,120 @@ class NotenRechner { return $this->calculate($rechnungArray['value']); } - public function berechneStringComplex(string $schemaRaw, array $valuesArray = [], int $geraetId = 0) { + public function berechneStringComplex(string $schemaRaw, array $valuesArray = [], int $geraetId = 0, int $run_number = 0) { if ($schemaRaw === '') { return ['success' => false, 'value' => 'Leeres Schema']; } if ($geraetId === 0) { return ['success' => false, 'value' => 'Keine Geraet Id angegeben.']; } + if ($run_number === 0) { return ['success' => false, 'value' => 'Keine Run_Number angegeben.']; } - $rechnungArray = $this->insertValuesComplex($schemaRaw, $valuesArray, $geraetId); + $rechnungArray = $this->insertValuesComplex($schemaRaw, $valuesArray, $geraetId, $run_number); if (!isset($rechnungArray['success']) || !isset($rechnungArray['value']) || !$rechnungArray['success']) { - return ['success' => false, 'value' => $rechnungArray['value'] ?? 'Fehler beim Einsetzen der Werte oder Werte fehlen']; + return ['success' => false, 'value' => $rechnungArray['value'] . " RECHNUNG: " . $schemaRaw ?? 'Fehler beim Einsetzen der Werte oder Werte fehlen']; } return $this->calculate($rechnungArray['value']); } + + public function berechneStringComplexRun(string $schemaRaw, array $valuesArray = [], int $geraetId = 0, int $programm = 0, array $arrayRuns = []) { + if ($schemaRaw === '') { return ['success' => false, 'value' => 'Leeres Schema']; } + if ($geraetId === 0) { return ['success' => false, 'value' => 'Keine Geraet Id angegeben.']; } + if ($programm === 0) { return ['success' => false, 'value' => 'Kein Programm angegeben.']; } + if ($arrayRuns === []) { return ['success' => false, 'value' => 'Leeres Array Runs Noten.']; } + + $rechnung = $this->insertRunValues($schemaRaw, $valuesArray, $geraetId, $programm, $arrayRuns); + + if (!isset($rechnung) || $rechnung === '') { + return ['success' => false, 'value' => 'Fehler beim Einsetzen der Werte oder Werte fehlen']; + } + + return $this->calculate($rechnung); + } + + private function insertRunValues($schema, $valuesArray, $currentId, $programm, $arrayRuns) { + $pattern = '/(?P' . $this->RfunctionsSan . ')\((?P(?:(?R)|[^()])*)\)/'; + + return preg_replace_callback($pattern, function($m) use ($valuesArray, $currentId, $programm, $arrayRuns) { + $name = $m['fn_name']; + $content = $m['content']; + + // Resolve inner nested functions first + $content = $this->insertRunValues($content, $valuesArray, $currentId, $programm, $arrayRuns); + + if (!in_array($name, $this->Rfunctions)) { + return $m[0]; + } + + $parts = []; + + $ids = $this->getBenoetigteIdsComplex($content); + + $runCount = 0; + + foreach ($ids as $sid) { + $geraetId = ($sid['geraetId'] === 'A') ? $currentId : $sid['geraetId']; + $runCountN = $arrayRuns[$sid['noteId']][$geraetId][$programm] ?? $arrayRuns["default"] ?? 1; + + //var_dump($arrayRuns[$sid['noteId']][$geraetId][$programm]); + + if ($runCount !== $runCountN && $runCount !== 0) { return; } + $runCount = $runCountN; + } + + $string = ""; + switch ($name) { + case "AVGR": + case "SUMR": + for ($r = 1; $r <= $runCount; $r++) { + + $res = $this->insertValuesComplex($content, $valuesArray, $currentId, $r); + + // FIXED: Only bail if success is false + if (!$res['success']) { + return "0"; // Or handle error as needed + } + $parts[] = "(" . $res['value'] . ")"; + } + + $innerMath = implode(" + ", $parts); + $string = ($name === "AVGR") ? "(($innerMath) / $runCount)" : "($innerMath)"; + + //var_dump($string); + break; + + case "MAXR": + case "MINR": + $arrayRunValues = []; + for ($r = 1; $r <= $runCount; $r++) { + $res = $this->berechneStringComplex($content, $valuesArray, $currentId, $r); + + // FIXED: Access the ['value'] key of the returned array + if ($res['success']) { + $arrayRunValues[] = floatval($res['value']); + } else { + $arrayRunValues[] = 0; + } + } + // Safety check for empty arrays to prevent max() errors + if (empty($arrayRunValues)) return "0"; + + $string = ($name === "MAXR") ? max($arrayRunValues) : min($arrayRunValues); + break; + } + + return (string)$string; + }, $schema); + } + + public function checkRunFunctions(string $schemaRaw) { + + if ($schemaRaw === '') { + return ['success' => false, 'value' => 'Leeres Schema']; + } + + $schema = $this->santinzeString($schemaRaw); + + $pattern = '/(?P' . $this->RfunctionsSan . ')\((?:(?R)|[^()])*+\)/'; + + return (bool) preg_match($pattern, $schema); + } } \ No newline at end of file diff --git a/scripts/trainer/post-handler.php b/scripts/trainer/post-handler.php index bf498f0..9948744 100644 --- a/scripts/trainer/post-handler.php +++ b/scripts/trainer/post-handler.php @@ -1,16 +1,12 @@ prepare("DELETE FROM $tableTurnerinnen where id = ?"); @@ -113,6 +110,7 @@ if (isset($_POST['delete_id']) && verify_csrf()) { } if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['xlsx_file'])) { + verify_csrf(); if ($_FILES['xlsx_file']['error'] === UPLOAD_ERR_OK) { @@ -240,54 +238,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['xlsx_file'])) { } - -if (!empty($_FILES['music_file']['name']) && isset($_POST['music_id'])) { - echo 'ja'; - $edit_id = (int) $_POST['music_id']; - $uploadedFile = $_FILES['music_file']; - - // Validate actual MIME type - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $mimeType = finfo_file($finfo, $uploadedFile['tmp_name']); - finfo_close($finfo); - - $allowedTypes = ['audio/mpeg', 'audio/wav', 'audio/ogg']; - if (!in_array($mimeType, $allowedTypes, true)) { - die('Invalid file type.'); - } - - // Fetch and remove old file - $stmt = $mysqli->prepare("SELECT bodenmusik FROM $tableTurnerinnen WHERE id = ?"); - $stmt->bind_param("i", $edit_id); - $stmt->execute(); - $stmt->bind_result($oldurl); - $stmt->fetch(); - $stmt->close(); - - if (!empty($oldurl) && is_file($oldurl)) unlink($oldurl); - - // Ensure upload directory exists - $uploadDir = $baseDir . '/wk-musik-boden/'; - if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true); - - // Clean file name - $cleanName = preg_replace("/[^a-zA-Z0-9-_\.]/", "_", $uploadedFile['name']); - $filename = uniqid('music_', true) . '_' . $cleanName; - $targetPath = $uploadDir . $filename; - - if (move_uploaded_file($uploadedFile['tmp_name'], $targetPath)) { - $stmt = $mysqli->prepare("UPDATE $tableTurnerinnen SET bodenmusik = ? WHERE id = ?"); - $stmt->bind_param("si", $targetPath, $edit_id); - if (!$stmt->execute()) echo 'DB error: ' . $stmt->error; - $stmt->close(); - } else { - die('Failed to move uploaded file.'); - } - - header('Location: ' . $_SERVER['REQUEST_URI']); - exit; -} - $edit_row = null; if ($access_granted_trainer && isset($_GET['edit_id']) && is_numeric($_GET['edit_id']) && !isset($_POST['submit_turnerinnen_form'])) { $edit_id = intval($_GET['edit_id']); @@ -319,121 +269,117 @@ if ($access_granted_trainer && isset($_GET['edit_id']) && is_numeric($_GET['edit // === INSERT/UPDATE Handler === if ( $access_granted_trainer && isset($_POST['submit_turnerinnen_form']) ) { // Check nonce - if ( !verify_csrf() ) { - $_SESSION['form_message'] = 'Sicherheitsproblem: Ungültige Formularübermittlung.'; + verify_csrf(); + $name = htmlspecialchars( $_POST['nachname'] ); + $vorname = htmlspecialchars( $_POST['vorname'] ); + $geburtsdatum = trim($_POST['geburtsdatum'] ); + $programm = htmlspecialchars( $_POST['programm'] ); + if ($selectedverein !== 'admin'){ + $verein = $selectedverein; + } else {$verein = htmlspecialchars( $_POST['verein'] ); $bezahlt = htmlspecialchars( $_POST['bezahlt'] ); } + if ( empty($name) || empty($vorname) || empty($geburtsdatum) || empty($programm)) { + $_SESSION['form_message'] = 'Bitte füllen Sie alle erforderlichen Felder aus.'; $_SESSION['form_message_type'] = 0; } else { - $name = htmlspecialchars( $_POST['nachname'] ); - $vorname = htmlspecialchars( $_POST['vorname'] ); - $geburtsdatum = trim($_POST['geburtsdatum'] ); - $programm = htmlspecialchars( $_POST['programm'] ); - if ($selectedverein !== 'admin'){ - $verein = $selectedverein; - } else {$verein = htmlspecialchars( $_POST['verein'] ); $bezahlt = htmlspecialchars( $_POST['bezahlt'] ); } - if ( empty($name) || empty($vorname) || empty($geburtsdatum) || empty($programm)) { - $_SESSION['form_message'] = 'Bitte füllen Sie alle erforderlichen Felder aus.'; - $_SESSION['form_message_type'] = 0; + + $data_to_insert = []; + + $data_to_insert = array( + 'name' => $name, + 'vorname' => $vorname, + 'geburtsdatum' => $geburtsdatum, + 'programm' => $programm, + 'verein' => $verein, + ); + + + $data_formats = array('%s', '%s', '%s', '%s', '%s'); + + if ($selectedverein === 'admin') { + $data_to_insert['bezahltoverride'] = $bezahlt; + $data_formats[] = '%d'; + } + + print_r($data_to_insert); + + + // Check if we are editing an existing entry + $is_editing = isset($_POST['edit_id']) && is_numeric($_POST['edit_id']) && $_POST['edit_id'] > 0; + + if ($is_editing) { + $edit_id = intval($_POST['edit_id']); + + $entries = db_select($mysqli, $tableTurnerinnen, '*', 'id = ?', [$edit_id], 'rang ASC'); + + $entry = $entries[0]; // since you're fetching by ID, this should return exactly one row + + $columns = array_keys($data_to_insert); + + $set = implode( + ', ', + array_map(fn($col) => "$col = ?", $columns) + ); + + $sql = "UPDATE $tableTurnerinnen SET $set WHERE id = ?"; + + var_dump($sql); + $stmt = $mysqli->prepare($sql); + + $types = str_repeat('s', count($data_to_insert)) . 'i'; + $values = array_values($data_to_insert); + $values[] = $edit_id; + + $stmt->bind_param($types, ...$values); + + $updated = $stmt->execute(); + + $stmt->close(); + + if ($updated === false) { + error_log('DB Update Error: ' . $wpdb->last_error); + $_SESSION['form_message'] = 'Fehler beim Aktualisieren des Eintrags.'; + $_SESSION['form_message_type'] = 0; + } else if ($updated === 0) { + $_SESSION['form_message'] = 'Keine Änderungen vorgenommen.'; + $_SESSION['form_message_type'] = 0; + } else { + $_SESSION['form_message'] = 'Eintrag erfolgreich aktualisiert!'; + $_SESSION['form_message_type'] = 1; + $_POST = []; + header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?')); + exit; + } } else { - $data_to_insert = []; - - $data_to_insert = array( - 'name' => $name, - 'vorname' => $vorname, - 'geburtsdatum' => $geburtsdatum, - 'programm' => $programm, - 'verein' => $verein, + $columns = array_keys($data_to_insert); + + $set = implode( + ', ', + array_map(fn($col) => "$col = ?", $columns) ); - - $data_formats = array('%s', '%s', '%s', '%s', '%s'); + $sql = "INSERT INTO $tableTurnerinnen SET $set"; - if ($selectedverein === 'admin') { - $data_to_insert['bezahltoverride'] = $bezahlt; - $data_formats[] = '%d'; - } + $stmt = $mysqli->prepare($sql); - print_r($data_to_insert); + $types = str_repeat('s', count($data_to_insert)); + $values = array_values($data_to_insert); + + $stmt->bind_param($types, ...$values); + + $inserted = $stmt->execute(); + + $stmt->close(); - // Check if we are editing an existing entry - $is_editing = isset($_POST['edit_id']) && is_numeric($_POST['edit_id']) && $_POST['edit_id'] > 0; - - if ($is_editing) { - $edit_id = intval($_POST['edit_id']); - - $entries = db_select($mysqli, $tableTurnerinnen, '*', 'id = ?', [$edit_id], 'rang ASC'); - - $entry = $entries[0]; // since you're fetching by ID, this should return exactly one row - - $columns = array_keys($data_to_insert); - - $set = implode( - ', ', - array_map(fn($col) => "$col = ?", $columns) - ); - - $sql = "UPDATE $tableTurnerinnen SET $set WHERE id = ?"; - - var_dump($sql); - $stmt = $mysqli->prepare($sql); - - $types = str_repeat('s', count($data_to_insert)) . 'i'; - $values = array_values($data_to_insert); - $values[] = $edit_id; - - $stmt->bind_param($types, ...$values); - - $updated = $stmt->execute(); - - $stmt->close(); - - if ($updated === false) { - error_log('DB Update Error: ' . $wpdb->last_error); - $_SESSION['form_message'] = 'Fehler beim Aktualisieren des Eintrags.'; - $_SESSION['form_message_type'] = 0; - } else if ($updated === 0) { - $_SESSION['form_message'] = 'Keine Änderungen vorgenommen.'; - $_SESSION['form_message_type'] = 0; - } else { - $_SESSION['form_message'] = 'Eintrag erfolgreich aktualisiert!'; - $_SESSION['form_message_type'] = 1; - $_POST = []; - header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?')); - exit; - } + if ( $inserted ) { + $_SESSION['form_message'] = 'Daten erfolgreich gespeichert!'; + $_SESSION['form_message_type'] = 1; + header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?')); + exit; } else { - - $columns = array_keys($data_to_insert); - - $set = implode( - ', ', - array_map(fn($col) => "$col = ?", $columns) - ); - - $sql = "INSERT INTO $tableTurnerinnen SET $set"; - - $stmt = $mysqli->prepare($sql); - - $types = str_repeat('s', count($data_to_insert)); - $values = array_values($data_to_insert); - - $stmt->bind_param($types, ...$values); - - $inserted = $stmt->execute(); - - $stmt->close(); - - - if ( $inserted ) { - $_SESSION['form_message'] = 'Daten erfolgreich gespeichert!'; - $_SESSION['form_message_type'] = 1; - header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?')); - exit; - } else { - $_SESSION['form_message'] = 'Fehler beim Speichern der Daten. Bitte versuchen Sie es später erneut.'; - $_SESSION['form_message_type'] = 0; - } + $_SESSION['form_message'] = 'Fehler beim Speichern der Daten. Bitte versuchen Sie es später erneut.'; + $_SESSION['form_message_type'] = 0; } } } diff --git a/www/displays/display.php b/www/displays/display.php index 3d52ebf..f27d68d 100644 --- a/www/displays/display.php +++ b/www/displays/display.php @@ -7,8 +7,6 @@ $lastSegment = strtolower($_GET['geraet']) ?? ''; $baseDir = $_SERVER['DOCUMENT_ROOT']; -$token = "QQa2UMbEYW8oOL7wz9DjtqECVCikSZsDuSdmzxiadEXFsKyujEUyQOW1AYMD2OqU8VXxClIRweRuWLzvBrZpPYL41e89Rs96tM7Lq1KpjA5E2mg2UfgvztheGRV"; - require_once $baseDir . '/../scripts/db/db-verbindung-script-guest.php'; require_once $baseDir . '/../scripts/db/db-functions.php'; require_once $baseDir . '/../scripts/db/db-tables.php'; diff --git a/www/intern/css/einstellungen.css b/www/intern/css/einstellungen.css index ad9534f..5ff1bb5 100644 --- a/www/intern/css/einstellungen.css +++ b/www/intern/css/einstellungen.css @@ -1,16 +1,18 @@ :root { --paddingSite: 40px; - --card-radius: 20px; + --card-radius: 24px; --card-bg: #ffffff; - --bg: #FDFDFD; - --card-shadow: 0 10px 30px rgba(15, 23, 42, 0.08); - --accent: #2d73ac; + --bg: #F4F3EF; + --card-shadow: 0 12px 40px rgba(0, 0, 0, 0.04); + --accent: #FF5A5F; + /* Soft energetic pink/red from Dribbble */ + --accent-secondary: #FF8A65; --bg-top: rgb(54, 137, 13); --bg-top-raw: 54 137 13; --accent-soft: #f0f5ff; - --border-subtle: #d4d7e1; - --text-main: #191919; - --text-muted: #5e5e5e; + --border-subtle: #eaeaea; + --text-main: #1b1b1b; + --text-muted: #8A8A8A; --disabled-bg: #f3f4f6; --disabled-border: #cbd5f5; } @@ -21,15 +23,6 @@ *::after, *::before { box-sizing: border-box; - -webkit-tap-highlight-color: transparent; - font-family: "Google Sans Flex", sans-serif; - font-optical-sizing: auto; - font-style: normal; - font-variation-settings: - "slnt" 0, - "wdth" 100, - "GRAD" 0, - "ROND" 0; } html, @@ -43,6 +36,7 @@ body { margin: 0; width: 100vw; background: var(--bg); + overflow-x: hidden; } ::selection { @@ -80,7 +74,7 @@ input { background: none; } -@media (min-width: 1000px) { +@media (min-width: 1081px) { .bgSection.open { width: calc(100vw - 380px); /* - 2 * var(--paddingSite) */ @@ -91,20 +85,44 @@ input { .headerDivTrainer { padding: var(--paddingSite); - background-color: var(--bg-top); - margin-bottom: var(--paddingSite); + padding-bottom: 10px; + background: transparent; + margin-bottom: 20px; position: relative; z-index: 3; } +.dashboardGrid { + padding: 0 var(--paddingSite) var(--paddingSite); + display: grid; + grid-template-columns: 1fr; + gap: 30px; + align-items: start; + width: 100%; +} +.twoColumDiv { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 30px; + align-items: start; + width: 100%; +} + +@media (max-width: 1080px) { + .twoColumDiv { + grid-template-columns: 1fr; + } +} /* headings */ .containerHeading { margin-top: 0; - font-weight: 400; - margin-bottom: 20px; + font-weight: 600; + font-size: 20px; + margin-bottom: 24px; + color: var(--text-main); } .divLiveSyncronisation { @@ -156,13 +174,15 @@ input { } .headingPanelDiv>* { - color: var(--bg); + color: var(--text-main); } .headingPanel { margin-top: 0; margin-bottom: 10px; - font-weight: 200; + font-size: 38px; + font-weight: 700; + letter-spacing: -0.02em; } .headingPanelUser { @@ -227,18 +247,21 @@ table { } .wkvsTabelle th { - color: #424242; - border-bottom: solid 1px #0000007d; + color: var(--text-muted); + border-bottom: solid 1px var(--border-subtle); font-weight: 600; - padding: 14px 15px; - font-size: 16px; + padding: 16px 15px; + font-size: 14px; + text-transform: uppercase; + letter-spacing: 0.05em; + background: transparent; } .wkvsTabelle td { - background-color: #ffffff; - color: #191919; - font-weight: 400; - padding: 14px 15px; + background-color: transparent; + color: var(--text-main); + font-weight: 500; + padding: 16px 15px; background: none; text-align: center; } @@ -248,7 +271,11 @@ table { } .wkvsTabelle td:not(.totalTd, .totalValue) { - border-bottom: solid 1px #6262624d; + border-bottom: solid 1px var(--border-subtle); +} + +.wkvsTabelle tr:last-child td { + border-bottom: none; } /*.wkvsTabelle .totalValue { @@ -290,14 +317,20 @@ table { /* Panel with inputs (new style, light) */ .containerDiv { + background: var(--card-bg); + border-radius: var(--card-radius); + padding: 32px; + box-shadow: var(--card-shadow); color: var(--text-main); display: flex; flex-direction: column; + min-width: 0; + /* Critical for grid item content overflow */ } .settingsGrid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); + grid-template-columns: 1fr; gap: 20px; margin-bottom: 30px; } @@ -309,38 +342,100 @@ table { } .settingsRow span { - font-size: 13px; + font-size: 16px; color: var(--text-muted); - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; + font-weight: 500; + margin-bottom: 2px; } -.settingsRow input { - padding: 10px 14px; - border: 1px solid var(--border-subtle); - border-radius: 10px; +.settingsRow input, +.settingsRow select { + padding: 14px 18px; + border: none; + background: #F8F9FA; + border-radius: 12px; font-size: 15px; transition: all 0.2s ease; - background: #ffffff; + color: var(--text-main); width: 100%; } -.settingsRow input:hover { - border-color: #adb5bd; +.settingsRow input:hover, +.settingsRow select:hover { + background: #F1F3F5; } -.settingsRow input:focus { - border-color: var(--bg-top); +.settingsRow input:focus, +.settingsRow select:focus { + background: #FFFFFF; box-shadow: 0 0 0 4px rgba(var(--bg-top-raw), 0.1); outline: none; } .settingsRow input[type="color"] { - height: 42px; - padding: 4px; + height: 48px; + padding: 0px; cursor: pointer; - border-radius: 10px; + border-radius: 12px; + border: 1px solid #cacaca; + -webkit-appearance: none; + appearance: none; + /* Removes default Chrome/Safari styles */ + cursor: pointer; + background: none; +} + + +/* Container for the color swatch (Chrome/Safari) */ +input[type="color"]::-webkit-color-swatch-wrapper { + padding: 0; +} + +/* The actual color area (Chrome/Safari) */ +input[type="color"]::-webkit-color-swatch { + border: none; + /* Makes the picker a circle */ +} + +/* The actual color area (Firefox) */ +input[type="color"]::-moz-color-swatch { + border: none; +} + +.containerImages { + display: flex; + flex-direction: column; + gap: 15px; +} + +.containerImages span { + position: absolute; + bottom: 4px; + padding: 12px; + width: 100%; + text-align: center; + background-color: #00000063; + backdrop-filter: blur(2px); + border-radius: 0 0 7px 7px; + border-top: 1px solid #fff; + color: #fff; +} + +.containerImages>div { + display: flex; + align-items: center; + justify-content: space-between; + position: relative; +} + +.containerImages>div:last-child { + border-bottom: none; +} + +.containerImages img { + width: 100%; + border-radius: 8px; + object-fit: cover; } .editContainerDivInner>form { @@ -593,16 +688,19 @@ input[type="number"]::-webkit-outer-spin-button { display: flex; align-items: center; justify-content: center; - width: 28px; - height: 28px; + width: 44px; + height: 44px; + background: #FFFFFF; + border-radius: 50%; cursor: pointer; z-index: 99; - color: var(--bg); + color: var(--text-main); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06); } .trainerBurgerMenuDiv svg { - width: 100%; - height: 100%; + width: 24px; + height: 24px; stroke: currentColor; transition: transform 0.3s ease; } @@ -975,8 +1073,8 @@ tr.rowStartgebuer::after { } .containerImages { - display: flex; - flex-wrap: wrap; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); align-items: flex-start; gap: 24px; } @@ -984,11 +1082,9 @@ tr.rowStartgebuer::after { .containerImages div { display: flex; flex-direction: column; - padding: 16px; - border-radius: 16px; - border: 1px solid #1f1f1f; gap: 8px; align-items: flex-start; + position: relative; } .containerImages div input { @@ -996,15 +1092,15 @@ tr.rowStartgebuer::after { } .containerImages div img { - max-height: 200px; - max-width: 200px; object-fit: contain; border-radius: 6px; - border: 1px solid var(--bg-top); + border: 1px solid #000000; } div.tableWraperOverflowY { + width: 100%; overflow-x: auto; + display: block; /* Prevent scroll chaining to body */ overscroll-behavior-x: contain; @@ -1039,4 +1135,42 @@ select { select:open { background-image: url("data:image/svg+xml;utf8,\\\"); +} + +.firstDiv { + background: #ff9cde; + background: linear-gradient(151deg, rgba(255, 156, 222, 1) 0%, rgb(255 110 110) 50%, rgba(255, 182, 130, 1) 100%); +} + +.firstDiv span { + color: #fff1fa !important; +} + +.firstDiv h3 { + color: #ffffff !important; +} + +.secondDiv { + background: #e0f7ff; + background: linear-gradient(150deg,rgba(224, 247, 255, 1) 0%, rgba(158, 226, 255, 1) 50%, rgba(182, 207, 252, 1) 100%); +} + +.secondDiv span { + color: #171797 !important; +} + +.secondDiv h3 { + color: #0f0f61 !important; +} + +.settingsRowGroup { + display: grid; + gap: 18px; +} +span.light { + font-weight: 300; +} + +.tableNoten input { + width: fit-content !important; } \ No newline at end of file diff --git a/www/intern/css/kampfrichter.css b/www/intern/css/kampfrichter.css index f81b169..f302acb 100644 --- a/www/intern/css/kampfrichter.css +++ b/www/intern/css/kampfrichter.css @@ -444,6 +444,7 @@ input[type="number"]::-webkit-outer-spin-button { display: inline-flex; align-items: center; justify-content: center; + align-self: baseline; } /* Variants */ @@ -460,13 +461,14 @@ input[type="number"]::-webkit-outer-spin-button { color: #781467; } -.submit-display-start, +.submit-display-start.start, .submit-musik-start { background: #ecfdf3; color: #15803d; border: 1px solid #4ade80; } +.submit-display-start.stopp, .submit-musik-stopp { background: #fef2f2; color: #b91c1c; @@ -921,7 +923,27 @@ table.widefat { justify-content: space-around; } - + +.editUserButtons { + display: flex; +} + +.div-submit-display-result, .div-submit-display-start { + display: flex; + flex-direction: column; +} + +.allNotentable { + display: flex; + flex-direction: row; + gap: 3rem; +} + +.singleNotentable { + display: flex; + flex-direction: column; + gap: 1rem; +} select { appearance: none; diff --git a/www/intern/css/logindata.css b/www/intern/css/logindata.css index b8aec1d..93f9e0d 100644 --- a/www/intern/css/logindata.css +++ b/www/intern/css/logindata.css @@ -32,6 +32,10 @@ "ROND" 0; } +.hidden { + display: none !important; +} + html, body, section { @@ -121,6 +125,7 @@ input { font-size: 0.95rem; font-weight: 500; cursor: pointer; + height: 39px; transition: all 0.25s ease; } @@ -155,7 +160,8 @@ h3.benutzer { /* ── User / Verein card ───────────────────────────────── */ -.single_pwedit { +.single_pwedit, +.newUserLink { background: var(--card-bg); border-radius: var(--card-radius); box-shadow: var(--card-shadow); @@ -163,24 +169,28 @@ h3.benutzer { transition: box-shadow 0.25s ease; } -.single_pwedit:hover { +.single_pwedit:hover, +.newUserLink:hover { box-shadow: 0 14px 40px rgba(15, 23, 42, 0.12); } -.single_pwedit.verein { +.single_pwedit.verein, +.newUserLink.verein { border-left: 4px solid var(--bg-top); } /* ── Form fields inside user card ─────────────────────── */ -.single_pwedit form { +.single_pwedit form, +.newUserLink form { display: flex; flex-wrap: wrap; gap: 14px 24px; align-items: flex-end; } -.single_pwedit label { +.single_pwedit label, +.newUserLink label { display: block; font-size: 0.8rem; font-weight: 500; @@ -190,12 +200,14 @@ h3.benutzer { margin-bottom: 5px; } -.single_pwedit .field-group { +.single_pwedit .field-group, +.newUserLink .field-group { flex: 1 1 200px; min-width: 0; } -.single_pwedit input[type="text"] { +.single_pwedit input[type="text"], +.newUserLink input[type="text"] { width: 100%; padding: 9px 12px; border: 1px dashed #999; @@ -207,20 +219,23 @@ h3.benutzer { transition: border-color 0.2s ease, box-shadow 0.2s ease; } -.single_pwedit input[type="text"]:focus { +.single_pwedit input[type="text"]:focus, +.newUserLink input[type="text"]:focus { outline: none; border: 1px solid var(--bg-top); box-shadow: 0 0 0 3px rgba(var(--bg-top-raw) / 0.12); } -.single_pwedit input[type="text"]::placeholder { +.single_pwedit input[type="text"]::placeholder, +.newUserLink input[type="text"]::placeholder { color: #b0b0b0; font-style: italic; } /* ── Buttons inside cards ─────────────────────────────── */ -.single_pwedit button[type="submit"] { +.single_pwedit button[type="submit"], +.newUserLink button[type="submit"] { appearance: none; border: 1px solid #7777778e; background: #7777778e; @@ -234,7 +249,8 @@ h3.benutzer { white-space: nowrap; } -.single_pwedit button[type="submit"]:hover { +.single_pwedit button[type="submit"]:hover, +.newUserLink button[type="submit"]:hover { background: var(--bg-top); border-color: var(--bg-top); color: #fff; @@ -284,6 +300,26 @@ h3.benutzer { color: var(--bg-top); } +.bgNewUserLink { + position: fixed; + top: 0; + left: 0; + height: 100dvh; + width: 100dvw; + display: flex; + align-items: center; + justify-content: center; + background-color: #39393941; + backdrop-filter: blur(2px); +} + +.newUserLink { + max-width: 600px; + max-height: 500px; + overflow-y: auto; + z-index: 9999; +} + /* ── Permission dropdown ──────────────────────────────── */ .perm-section { diff --git a/www/intern/css/otl.css b/www/intern/css/otl.css new file mode 100644 index 0000000..02a6a3e --- /dev/null +++ b/www/intern/css/otl.css @@ -0,0 +1,120 @@ +body{ + overflow: hidden; +} +.page-secure-login{ + display: flex; +} +.bg-picture-secure-login{ + width: calc(100vw - 450px); + height: 100vh; + position: absolute; + left: 0px; + top: 0px; +} +.bg-picture-secure-login img{ + width: 100%; + height: 100vh; + object-fit: cover; +} +.bg-secure-login{ + display: flex; + width: 100vw; + max-width: 450px; + height: 100vh; + background-color: #fff; + position: absolute; + right: 0px; + top: 0px; + align-items: center; + padding: 30px; +} +.bg-secure-login-form > h1{ + color: #000 !important; + font-size: 32px; +} +.bg-secure-login-form input[type=password], .bg-secure-login-form input[type=text]{ + padding: 5px; + width: 100%; + max-width: 300px; + border-top: none !important; + border-left: none !important; + border-right: none !important; + font-size: 16px; + border-bottom: 1px solid #000 !important; + border-radius: 0px !important; +} +.divShowPw:not(#lastDivShowPw) { + margin-bottom: 20px; +} + +.bg-secure-login-form input[type=password]:focus, .bg-secure-login-form input[type=text]:focus{ + outline: none; + border-bottom: 1px solid #000 !important; +} + +.bg-secure-login-form input[type=password]::placeholder, .bg-secure-login-form input[type=text]::placeholder { + color: #ccc !important; +} + +.bg-secure-login-form input[type=submit]{ + background-color: #fff !important; + padding: 10px 20px !important; + margin-top: 25px !important; + border: 1px solid #000 !important; + color: #000 !important; + transition: all 0.3s ease-out !important; + border-radius: 0px !important; +} + +body { + color: #000 !important; +} + +* { + box-sizing: border-box; +} + +.bg-secure-login-form input[type=submit]:hover{ + background-color: #000 !important; + color: #fff !important; +} +.bg-secure-login-form > p{ + margin-bottom: 30px; +} +.seclog_home_link{ + position: fixed; + z-index: 1000; + top: 30px; + right: 30px; +} +.divShowPw { + margin-top: 10px; + position: relative; + display: inline-block; + width: 100%; + max-width: 300px; +} +.togglePassword { + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + cursor: pointer; + transition: all 0.5s ease; +} + +.togglePassword:hover { + transform: translateY(-50%) scale(1.15); +} + +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +input:-webkit-autofill:active { + -webkit-box-shadow: 0 0 0 1000px #ffffff inset !important; + box-shadow: 0 0 0 1000px #ffffff inset !important; + -webkit-text-fill-color: #000000 !important; + transition: background-color 5000s ease-in-out 0s; +} \ No newline at end of file diff --git a/www/intern/css/sidebar.css b/www/intern/css/sidebar.css index 4a9932c..98c14e4 100644 --- a/www/intern/css/sidebar.css +++ b/www/intern/css/sidebar.css @@ -1,10 +1,13 @@ /* ─── Sidebar Navigation ─── */ :root { --sidebar-width: 280px; - --sidebar-bg: #fafafa; - --sidebar-text: #363636; - --sidebar-hover: rgb(var(--bg-top-raw) / 0.2); - --sidebar-active: rgb(var(--bg-top-raw) / 0.35); + --sidebar-bg: #111218; + /* Dark navy / charcoal */ + --sidebar-text: #A0A0A0; + /* Soft grey text */ + --sidebar-hover: rgba(255, 255, 255, 0.05); + /* Subtile hover effect */ + --sidebar-active: rgba(255, 255, 255, 0.1); --sidebar-transition: 0.35s cubic-bezier(0.4, 0, 0.2, 1); } @@ -18,15 +21,16 @@ background: var(--sidebar-bg); z-index: 10000; transform: translateX(-100%); - transition: transform var(--sidebar-transition); + transition: transform var(--sidebar-transition), box-shadow var(--sidebar-transition); display: flex; flex-direction: column; overflow-y: auto; - box-shadow: 4px 0 24px rgba(0, 0, 0, 0.25); + box-shadow: none; } .sidebar-nav.open { transform: translateX(0); + box-shadow: 4px 0 24px rgba(0, 0, 0, 0.25); } /* Sidebar Header */ @@ -42,7 +46,7 @@ margin: 0; font-size: 16px; font-weight: 600; - color: #111; + color: #FFFFFF; letter-spacing: 0.5px; } @@ -69,7 +73,7 @@ font-weight: 700; text-transform: uppercase; letter-spacing: 1.2px; - color: rgba(45, 45, 45, 0.35); + color: rgba(255, 255, 255, 0.35); } /* Links */ @@ -95,13 +99,13 @@ .sidebar-links a:hover { background: var(--sidebar-hover); - color: #222; + color: #FFFFFF; } .sidebar-links a.active { background: var(--sidebar-active); - color: #111; - border-left-color: var(--bg-top); + color: #FFFFFF; + border-left-color: var(--accent); } .sidebar-links a svg { @@ -134,18 +138,18 @@ /* Hamburger Toggle */ .sidebar-toggle { - background: var(--sidebar-bg); + background: #FFFFFF; border: none; - border-radius: 10px; - width: 44px; - height: 44px; + border-radius: 50%; + width: 48px; + height: 48px; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; - box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); transition: all var(--sidebar-transition); padding: 0; } @@ -174,9 +178,9 @@ /* Footer */ .sidebar-footer { padding: 16px 24px; - border-top: 1px solid rgba(42, 42, 42, 0.222); + border-top: 1px solid rgba(255, 255, 255, 0.08); font-size: 11px; - color: rgba(42, 42, 42, 0.485); + color: rgba(255, 255, 255, 0.4); } .menuWrapper { diff --git a/www/intern/img/icon.png b/www/intern/img/icon.png index 086ccf4f6379331370076994c576ee1ce77b0c12..6a64b0c1d866c8109a1e7dcd9058c0bb8e417ed2 100644 GIT binary patch literal 9871 zcmaia-QA_QwEVW;=MQ*Z9QmA+ znaN}_ndC~s|C9THf=GY}002-VB}5e=&jQG`0fdL#@76rZArAyQ2@OX80CnKs1(nQ* zN(cau0VG9*l-;r}vwf|!my@@9j;G?1=pwS%21Qd0&EFY+uhogtq9j;ToQ5|uRYx=p zA)H|$=qp?nFgF8yoo2rWq+uAZ-9TFlX%2Etk`m5|*4?t~#3>SlCScmDo>8FA1e<*g zPl^W5Ss2ncpX7&N@g7WcwD@*%FTA_i9{p*xJ&Mml)9>}laKCmq8h5QOoB8Q6p7^^*)Z|s|G@FCh+!mdhaNhDLA#oWS(>Z?$jTl7pMx^f$DTNu zaBjdYk)LcbNi0HDIfxkT8<9rF-_1`wrT6+9icMh}L|+RUOH`Zz&{D<2U?ky6bH|;w zCZZYT;L^K=-9OpdVap8PP;n>V)OXr)V}`-WBw?6bouEPmY9~)g;)ihTP9T76B0g{N zL_N+dSP;0T?JQqM2>Nx4w4WN%MO1`qWkxQrSxv{F_Cq0E-zXvs9JOKwN~^QZ+N4B(we))q*fA`%4aaoYb9Njv%X zkMjE_F6<0U+A^(_evBXtbYFb;4e6xO$FF=!DMr9^lNopuNgmac~bfyJ&(cDdq)vXz_oN2SE>$tfQ(BQlc z=m{|y=)QgL-C=KYxCV`7VSYEa?I2f18V+{*zk7A>6|Y2gfWsOMrlH&Jo19%Kv;w?y z$WlySe5WRpbF;T?Fy@#<1Os_-)U`j+!H3~rnsVjq#RB%ACc%hsdD*&AoJe|+_Bx2O z3~HTlVI(ttjAFMk*3M;)ymG2@xv;g)IK9V$j5UcM z@7q(*=kJI+BmkJ+CANmn92KW=4@7E2BBI~gdT!HcpPrlt+c68&SXQ-z!b$vO?}Ky0 zMtw~5-Zzy1?NAm>FW~bDDE~koB>kmi(E57v2)i1qh)0qYQCd=9_j8S=|2=-&m8Q&N z@RI=jwa=A7GKrszYU@|POIb!_G6p%oETzJp)sNoYwRoxfSvj=xt<7{3czfz17T-OY zXxCLHV5fZcjW}%}WMCl*QZBB{wHs8Sn1P<@Gx+FlA5I= zprU)%sVRRt@qkzx1OJ9^fxC#USAw`?aK$xlX797_%U z7mP5Qw;+1~{YO;t8K|j$BeV8wxSzwh8`6)KRuYy)o<^wIzDb3xLUYia_WaH6vx_N~ zVkv4@N2NhhUdwcDa>WdEz!h&Xc&VLf%+ki11otHiK@^M}#q_$?m8H-KQnS25VM z{GCADfCK6bgk{#O4vsYMQwVpkew&B=s&)di+s>B#<2&Md(af){@kAa3gC5EXuK-w4=}1Eeafc*4_9&S;4pO>r%()z)5lZ94;S6X6<>& zUp6)qD@z0EoyN30x^89wZV04U$FW35)k6z)tj-GQ>OBlGE z#6(}GI?B(Iy&Ib~xe52iPy6Unn&OP}4hxg81iUqpP zH9KkvjU6w|gbEja@r-K5mkbBhlO(Y)$n>*!Hq4i+%Dm3W{Q@1t;X$RJ369<5mj1{B z{qMrn+HIX%JEHA~^k-zu$)WLP&d9rl9m%^lIQd|i$?T;ncOrUyaG%Eg6{^=sPhvu0 zC63}Ac_Ib`pc!*IYW81xVSB+yCP(g=QgiXx-9z{%m@Ro7N~gslKC z99f|%aZ5tWF7bIVl6`%ss-BBy7~l&)6U+e$RcxX=#F^BE9kRq*Lm&07I0D2464Ht#L3zrt*{bNU8NYTG3Ugc} zlfVjSDH<|lRZFY+$@XnLV_R==N1drS#jQ~9UE(gXZn?^zvlovES6 zbz|g4)MH(kMCY{Y)uQep)77$5dA{B-5=62f2)hg@(htG&K zd^On>yV9Q(Y&~l>&ryT@{!vz3CLdLf^5$cE$a9lY0vW4>N+55p*t$8cUMU0n~8H^F8` zVw*I+qJ$Te_&mfwCtQXyCwq#IJk2%~gMWmNfFOP$_&0}$S<0o`YRqRYsX=5q?rTgU zF`r|*-zl{&%kc-6y&{9jFsF2MQn+1x-bvGer?w5mP(!vWBmQ>7?pikWocUU8_o?Pxw(stj{6M24OtArDEi=6+YPhw36L6MH z*5LM1rrt886@8pR+&8ElNL;f#7fmqEf*)=1^}EDqd*XoZ0al$7vVvlm;%0qsZDtPZ zOYxuTP)d8s6s3AO4rlR%-mTW*-{UX8BEsj=I~c-Mq}Za_)H%Lbjn zY8z3mn2lJV5dsFQc6A7-ZQg3Haw0oS!i!&`+TO;e$+%O2b_#!|P}xN#AQL@AQmZpT z`NAB(nX6tawKjLG1&*P!MOBIQ%R1VpDiWU(28+-#j$q^;?uh>Ia(U@lacdhWFtxNc zl>){ac}v1o9cE$ZLzUs6gR1JEq%-ryhFQei3Ww&tI-qu_+T^(H{r7IGm1DJ%^(a$@|?_HR7r&mPbAitGtqAzq0^}pr9w>8X})Bmal>_ch% zGV|MbCuK_~#n>tKyo!`ZK>(^bXT^xMQgXWPO<%cUMVVh|;1oagVo3^ytNIloi#+y) zL!zCO{IO2zl%@hb^ArU}iZs&TajY~YbZ9>}yTk1^cdka|^eCSEgKrV7CJ9b}sJM(L z7(Yl@h+OoPkIpJu7?FfX$;>V%lNUfSaGU}T4n}c7ub+Bjd}+(*I6{0xXoQZRzzP%x z&;D6uSR2sJwsXFR)sC=R9-G|qeZxoK)u*wRQemjGe%2cMR$o!eSb=OIsi@12wClh) zQ1H6&X-aIRw1l3b`{3vW|6XK_x-Zg)CZy*yAoP!wQGSQ%sEwZJTF$C1 zU+qbxeCX?*QXzD|v!!0UHX7H)o=gznIp?57_x%+${7}1I>Q_X~oXY!u65Me`#=op! zMSo_uftS2yoLS~ZBP6-r?_9gDeRR`eE2&jXwkhh_aihK-_CFUJtd3d($SWKNI~b|2 zjsgL_Lz&v)|M7P^Opa;R2l7c{fNu}MBIFKoa}Hs;B0&)2$YhM|ti}(U%18}p^ynwu zDCCrKkdkI_FSy(Kp&eb=UunLK3}`y29-0M0XLD6}PdE$`SCe9)`JpuN@Y@Lgq)sjx zezsXQWD73BNl&Xg3ND3XKB$LLgO`F;-`NSi!$pxkYARKaVJso!1ir`0uku2bgLHx% z0u#MTnfPeO?PRL|>+}&OHl$5$J8MQ794zs0Ss1}MtDq8r7M8LPTF-+8{5Ra^T0_M5 z@{oOaa(u~axkUkOqr{s;COkdxBK;{!>^TRTibX_N8QDx_QBm}Hu-JAaHtt*T3A-MC z5M5PC9bKP(@90%;nSLB`tKC(?u0VA6^MYSWUP)MH9n{QG;P#)Su5t^?r4pb&Mo9k( z=NA|JEKhcV8n?Hqm4iOh$5=prLL|+Mw27k-GnpiskRmv@#IkS8%q6Qx*Z4A`mdYeI zY5}4AfI>^@43DvkHPvoYSkOU3To4+7wSHz%Y?SQGB%CMXC|V}gEQUuKI|+(EwZ{~7 zYBzV(xBZJh>9-`=!z#c@ZkUehmqJRkR?>v(A}uCHM{(#Tgy9r=M!VcE8cPQ&jGQ z^mI>dBZ1CFO@{PsJ*6W#*lpiT0F7s~m`T{*$l_B|gj5B=O-O3=nu?OIV2kZ=+pFKJ z8ef(=+>`Z77La6u(|kQTk(KSH`5256vE%62uYPb_6v0yos{XfUhS}+AM$a4}(XKPP z=~v=Aw|08#kop2U%qDT!V>$)d@U$B?R?{I{tI&^_ZT>wg4LnCqFkbj^Jk=TMWolTH z%8#y7W9elkv%Tu-k0EbXjR{pjNf|-_O-&Ofs|qv&Nrs#vmYA(N8C9VRWj#0f-S}a5 ztZ8lu0c1kJm7nWKw`oX6wYs99gK?s2CxcQD#8|5eNa`RS|IEh$Tl3k^u5uxuCwdk5 znO

Gd_|r2YyAZ<2yA~L)PasE*$BgY-pUXZxu75>WIVzGernH~mzP0G^J~ zz`{3=V;e{_jP|tNqkKf(NQr_o(cgV|Zw<=c4MGZpscO@b&=32lv(ITAYiMHZjc2z^jZD#+ z0NEb}>oCiVvZSFUShknxjp06?TWnoEJpLZ}>Y`iRta$77KDJlcrG9)GI-faX>^x_w@{tkV;Cm0gz=W=6P8zS1JjO1#Ih`})&U zo||wA*El>bntL=hOj^BfJx~xZoR-yVip9Qy4 z(;6&9wDqXb$aNLRl_QmiP7d(mZLByxj`iA{El+<4`0CFlG4f%&U;Iy@tC~WY)U0L^ zyT3g7pYn5!&hy;O*4&03!V%fLRA$+$gcW7kp1D2SGl)KiYnjs@?6(R`M$e+3@q ze6ruk`IOz=b)l{E3^WyZv^u~aiAYfKP$)P6G{sO z>;>X%mnVt4eQldQ$*yJ)d+I4uisdBJP><;%b}E=9d*Hn1fZoS4Wmx;i!TEK>M}iKF`~z6$vM`?9F0~Jn zdu~@7vDCY6vX*DDxN8~#QAjszsd7i!)9S(+6tG#=wWRQN{YRc9&9#Dkh!MI$rxHO< zh42^Ao(C62j_QrCSB2YNaxa^)-LLC>zR$Cv;|S*Ad+EhICO#jrKsfH*@%-$Sjt5;U z#1UyBY|65dn@m1ZLPQW9OTWmEB-Kki!?%_Hhu@h`RbAguQUwe=9@XTuN~(@)Q`cF- zO+NSAZatstF?-$D7;6n9$J&_p6>4eLdP+w+DVPkns(egG4e9H=I%>7}j!Ohthd!ai z1G8RMU(yO`5M$Q(A6%!pQ7eQZg$x22(Z^1{S5bQ6>a4$g-+D3lo%p4v?XK>p^>g#G z&0rx4^NMZ@5tBd9PwvbA%R~D9kdVACR%rOdiOg3k{9+(np#-vYvnl~3n z;#DY*fg_p8Jmc%XrHW)T*rG{``;01A60##2B*J|4&%u3ByY?#7rhxU!{r>x*Z~OYC z;U-n2!^6b}b(?9~aZ_1u0nCl@PUNV0+uxU7HHV_SjO05!>kdbty3cnD`LaU?-OKrDReor2E(`uhw`f35Dh2|@6m7o8ZD$Z3&OiQ*b={Ji%w=k!J68wgt}ZxL6*uqJ zNU2PosNP^9BZnhf0wqr7Hn({_5qlBtyml8rRz!Ic+!k56Th){#vT`}kcW+}$g1R`? z*B@@j2^sHeo$X#6-SsOBd?Tw0%RIQ%Rk<4krF@3PM&~o=#hg{;Fz~9M1F<08g1|!z z>=-&PgUBw&!PR2w!{j*Z7@V@Hw_d+w;zyrPfeaM<7F4DOW>LX`TJUglfT> z^I=pIM+RPltc_FMwJB!ht*P?p8(&kv<)xI7SSf8VosFQ8hKS%)8=PAc9|?V9kQ#;H z89UPyl1}7I;l_^m9)u4SmBngB=!JL_6e!8bjcD%gt2`}Kl91CgANWP#)`PdKAxpGS z%FHMJ`?!COlV%ftELyGLsZzJq&S)95CLbvBMflrS7lO3svX>Xld`P;e2-a5>Xn*rq zP~Ll`$hcd{l$s^f4*FtBsO8gG^)Ty*^^_ZInY+vk__wdJYCxd{RlQ`!jZ z9jCuKIAK^R@Yjaj)%5M@;Sr+nV(wZDFX|Bb2()TC32NlF<^5-}NSUqr1@|G5VdFuH ztYF?oO(80dLA0xTMo|S7(n71*Qj+?Vt-IqZ>B0yW@xj@6#Sl@F*@o3FtokPjfykPX zS4SMDwyk)ew-Zwus~KOX?a7r#%@gRenNwC4a*>AUH`CH258};Idu4eu7bbO%@*oUJ zP7j0kx!TLjYJ)Y@>+|L`lX#e2k9`xGx)v7}MWzCryu5p|FXjZ9H`CiM-RVGE*53$y zYzvTt*ssUvWjgt9g`&Z=H}29wK-#YQ5I>IPtP}rWKyY-3^-uGOxi9}Re~^^cX_O@f zk%)W?V?_E~K+&{pd3Hc`z2h<>{J)COaqOP4#aW0X z>nGF4WFe_ow%4vMn%;w-mcQfm(WSLSGOFPsSJz#wX!@HUy@^j7Et;M1q<$`jn<;A~ zV$Tjj(yKG<$8#A~T0?;cP3Y{}j<-&-35~?ATy!+TebP7zK{l+vooU6HWtF;t8i5$P zR5j6d)S}FaB@(lrR;jb6e3(a=-Hp#BtCKUkeC@BhUQ#b75u`Yf zaq~8{Frp`?(moxx6!(rr#$oj78*4kj(^juK^{Q6pySW`|`ec+qkE`W7X=dL9;xV!c z`=y;Ytm!M^GzY0qFl*I^Fqai6@T!3oss_e{1_w_*p+j@*g<1v3Mw(rvNNfK3is}({ zJ=L?};-=RUXAj-=g@H!gHw>gC`%uYbIa*vxFUoFpYBER=L5u4dCG`&DFNmBM)MYPG zd;z`>1va_orw&%T)bjn{;2-Ty;>3!jp_Nawdh>#W+Eg$VC!+YqScTt3Ph#B-xKe^k zn^G9xZ_L`8TRE+i=P%}!XLz|XbF*Wk(c>$YS}<<3qkPcw^^Ss9S8Bt|2Tv@@Hr@8> zia(5ump6kQaXSFojRGX{H!@Lw(er)(QGp8j-akv`RUCz~VmpqCb1Z&}QFZGEx{-;0 zgw5#P^;=y`pd%fHIvF>(&sM;tW=*fCTe097eOgMy`$H-GF$r<=s6?54%|3r;QoOfV zq&~iT)T)yN_oG!)CdpM`LbffB9P^7*km%1pT&xpA1!6Kk5LpIcO1v!xeladzv>tf< zi>V)lZlD3=sLl(L`2+t}78fGng6Tf*NHOx?0WaiV8Xzb*Z5RB%V*bm~hDb!~uEqOe&kCWHT%n(d8+P^tzd zOFW`+=vWdJag>{#hb9y~frW2G<$wBtoujr>jq3We*F**P(XfofR>vcgs?4PktF zc=uccU!r1%O}sE9VP?3E@WW>HC}8nc*m}fA#CghRxWHQpHx4wE}~!-H>n6+Yo-iu)fg;}^)oJ4`6 zLhT!g^eP@<So(m zbkn_T1oe{U+7LrB2Bp8QW(8q(XKw;XO#RQbE?QB7OjeIu6kY_013e~~M|bp>^LtpK z2>CMOmaAnREDT@s5?4=ZU^(c{4U%zCo|>*q>5(+tuS!|zJ4ARqkNsDxLvp{i8dpK> zQi?e1*RmZUyTsOv>);Sg=+ZQRs`N(oyb!YQWY0F1v6MCYz71nv zW9-Imez*7M_x&Tj*Y(xqDlzxm&vT#iIFIu<=N782sz6HokQf4ikSZz4y@NpT*RMZs z-va-ml0CW%{vvWz)OCSC$l9(y@#471=pc|s5GA=6njR@zXzLWJvBugxW3950%4ZQF zilY!_<}C1s`7_C*?Vn4$HW5iG4$ng$#?oC{3TZFJ+nP|TED{ql-(I{G5)cv+mJvc6 z61LSlJTmP%aoYS>=q<~$R@aHL`hTZQ_303;0TqkFP1i9o1p=^>|L^1fv%vqWEg-Y2 zgTmu5&X2rUrlQy=K`#U;%2`NDVQj;zp}X=lDSI2A`uh5vPz>__T`ag~`O|v+D~*KT zZnD}UvJIvpw)h1PrpuzR?K2&zmo7ywxTU&J*F=S+reNbH zb6eRsc(A2z%uM|@TH4wY0wb{{%?#VSAm3S3W_YmvyQgbzn4pReN(RsucDySgfh zFZujL&&T^1wYblf3q2FrG7?@$?DLI?#zQf*kB_d?i-xz~mR#7LuE7ev^0IQT&CMG( zDnqODa#PGcmqF4yxBWHZ;VB6Ia=vX(9Na26=W9Dl3hYedm?;x{I4zBBAXu|_(%@)h z@dHjE_r7UD{N05ZdDZlx5*_(SWWe7BvBXm5Pr7${X?^4l-(o@pD8CO#Q2lZ6b9Xms z?NF(t?<^RB?G@^9pIv=jOLYo`6VBhiGdT3PxuLqphk~g4B_kr_a3u1!xM@UcSCVNp z^fhY(Hnw5M2+gN(pP%a)*X`h!72AiEn>v3QOYY#iR-rNOGf<&KyD4R4YY}%(_o$|J z`XzGis#ypep7t|fXb?YUz@e*FBj%{txS)c0tV<=Q=b{K}#y(2yyrnNZu>XM8RuEjgio#i-PZku4(Z(QzrWr895t^6P(yLI1FHxF3a z6}5GA7^^~riG1XJ@@ZLTZ*3F9%pB8`m`Of2*H-jjn1y6&abHc+?-|YDm-~5e{CSb{ zLneW(5w(fA0`!7;b*c?p!})l_b(Bn;VA*K43ov$lQw{vj)Gp3?{hy8)%FRxY5f$2v z(-))FO{z!IUz1WtZ=fE(5OR7~hz!xRcCT%lvfQ!y0AJ!DHkC8*2w@DDH^*IKFaNP) zJ3=U;kLZNEQPrETnF8UoZo_rH#{Mo{&;Ktzx$9Tfq$O&anv9?~cj<4fum38y)a1E1 zU`mdmjG)u=Ug>Ue{1{NmmM$_k2ICMiU3LXuSuCBk=zu6{l=OMCQlE@dfZ`j&kKCJ{ zPT+REr!S$WFJHi?E1RG3bm+%(8)DUMZKZA>%R!$|hT4g44F;-}mX%rBknZ01XlG!6 zFK%chsw>{8bjUSbcEki_ob6T91yK=Gj%{;PYj%rSV)PLDBb3D9b92Kd334rZQYLcp z;OL5Vwr8MInGES{^u%@QpRp%;19;@-0=m@aGm&!U?OkebYSXo)1MKH--DR-Qjn~jM zCtMA6W?PB4TE5ph%}zXPgz`#(2hv4E7aF4*K8C;*?(*ncu#TCij%+)I^Y5pCbD{}m z6#I9kDejwg9ceqW7}QvgvEffNo(C zDo&;!^4$%~p?mt?%8pWWsfC>0)o_A&!gH+j{*Pm6ol6&B{_t1X1AM;r*qtgUq>Q9n z<@W2XU6!RHc~;;Rl-^e}y*E)5F9e-@T#RWv*>IS=N?`Dl z$=TcM8R5K*h03xTBls;S)oH5GFEmES#tG>*~0+hfRTL~l-M zBOhC(rH%`z%hg{;e{Orh`N0m|6s*sDA>>jBY+o)rreP~A34rNJ=i)38PQdLS^Lasj zx-V-&kJ|)nk8>J9hef$Wk(AY~dOyWbXVC9H4$S(+tt>tkbi*avQrEc-E;|U)2LaKz zP*0j5(mVn#H%PV5_ROJE&J=5hxs@?vc)nEBL1%iST&lbO->`XtQ~0WM-O-t>f7qgfQ%Mo#h_P#`#8#Rg$^Bg0%=i7YoknXSapQhw+5JW+}&2 zbOFxr-;Y`TiNI!j@~%&7qoOB$)=PyolnRN6gZBSO%gGBqXmBw&KeboqDa(!nR)2WrzD z-%d*@Q_=<3XmBHLk#GX_NLcNLc4(hIUE1>wf)%eJSh>#Ol7<>%UzX!<)%ljsS+uTS zpTxz%)!#cO{Ifat0D<91ym}XN>&e3LER3O$fr4u2r*FmoC7eVQsZ8D3`CNx|bl>Wk zjl0K>SVdOV%LB=po2zMeIoNKka}>Vms8dG%;ptQ9H@e66jJ$Dlyi^D-Zr?w&JvfZA zQGFhiUinVHp;l~WbeX{7{_2|!&$q}-A6m7>ryciRyC2axjxr4=_9_Cm-8?;#Y_8r< z)t+pjm{bD(rCDBE{Tlg4zER4@L0KAeyBWE0c4W#bbMU#DJ3-Ji&8H#vHL`Wb$fwke zoI*?;SjzC<%gSmxb^1F4=*kJH;D`%XbP!iHw4u0AfdAtj*8ollc!DLj)R!#r)%7HW z^rYDnOQMbh=>_?+<@!(pOPo6?-8juH8xf9hRr)!fq!5Xp42zcGMqSw0c^|e_RZ*d< zjz)4TOM*@}>620&4E<|z=|X!t?V0_e^zOVqeL2)#R$q!IiP=?88KQ`NJ&4}-UGx2& zGPAd}nA=}px;UKesjT@e(dFCZL(F+NL|7cV3f8nN@&>GCmPLoPknK0&&pFvcZo7yn zb5K_{#dZ;#-`^Q;pnrO2P`Ueo*n42;g|7cU+p%`9#)QvZA$G9uQFO)k|r?>r0 z+n&id1S79Jj2A^}X2hD*IYzB(JhVjVRT*7>`zx=FyH@WP{;h{g?LBUb)H z@&zzk!S|8i(?7W`YbE+fbAh~Ycre0X{G)O+r9j7IVuYX~_>nzg?*en(8999W!y@Ck zJst7XjWYDY$J74m)PAq4jZSTwV2Iyu2!p)k6x%c7p0xw#-cceYgg#gFDPL~n5N!AJ z%NH#ZhK)`?;K9Z!X(?nh#KVZ=P~QyoXKFSe7)+W2BkLuS`yz+7cPqBh?nt-x;Zs2X zV9g%_BD1F5o7e4#`u*0mH1ZLLLy@~hR-;nyYgI!-{vvl)A7mu_ja{OPik^RS`kGXN z8}R~~Rh+nw^D$jHMr@#QA%8Z<9cs0atv$@qe{;;k*Jd)%cqc?6O&s;vQDw8N%v@E_ znc>0th;i6%_DzzQp*%MBb&|GAWw$urczB?(kg#a5wMcDyg_&p6tlN&Qy9|v+C46gH zkPpQ*_1z5Gf(hv~-SJ=ge9#Xl*u{19!rDS~3YkCNv@kzV*CCq#>u#u-d4&@7BebEz zqsy+TyXvOj;K58!D6ye{sudI>q)W@zHlF@s38!v6l@m@N*`iK|n&`eSEp@>>X}&s& zx@L@XfOIHLG7o^wJV_N`N#I$smMbs0$Z(5r{C3t*Dwvmh%Sz$otpIJx&Bd6$enAwe z`M_fRvb#5y(Zhi)c7e1MbAsAN_v>KKQtALJVA^{e81u6j@m|?+H8Ys$q$lqWio(w% zqP&v!-VggS)ZhNK6*CZbr(NVCWHAt5YV6j1>p|GH6lT=NbYZWiN? zQ*y2|m?pEiI{o@b`M}uPTQOkE<#%-JoZ;S|G7#f4-;c3O=oxvraqF5Bc|gY1O=X`M zVMDcbNRN(EPn`2xx%G2=)!H2zvoGhuSUEXS&t-6ZxS1yEtH#q4V{(Q8$#KXj>2|1m6z|VR#A7(?Ku34A4rx29!?phpIl8h z2v?=^AE;w=HE70DxEymz;YTqTjoa6h&Ura(_~h;5@q&Ph+3^418Uqgu&noLzzG=g2 zTQK8@$!jIPX~aJhui1Uadt0m&-TutoLYbVRU~JnlRPclP)cAk_{8W6zQ}}pL)YHKVUp69>J|nE4KJss;#|S zqGp=6Z(wdq|1~oYAy~HTLzto46UO#zICsSenc#LiY7-?)e0X(aTM-@-h{Fyh10hu; z{%uNLMUDcwTp>eXiqi%$J>(y9<Sm<@BdFNn&U1gGoZcHXvjkR_3{4Z1{C)Po$;K z`xy4X9#!4wgS{8*Z-3niN;96@)YmpV>dTO@!;|J<&&VMgf<+2LeJ+-W) zQq2sKLhBRND5C{S;3?S*$%(D8Wa6%Em?^tR`2|FF53id@si(sbsL~#V05{L+7e~U% zLs+Y!1}0@bd;@S>hW}KP?|s>Pr$6b?lm>kR%}U|XPl76ZKBz>T{WRs8uvUN={ql|q zjMP0CLg9u1`s#3tuQi(U;a&sF7G}(($aL{%vvfI5dKrN{5XnzyEAqXFTfnFHW>ZHwc>_tc8-bkpSWK6~NG)$9H$LL%GW)^?Kx_*uN7=JQk` z>~kq&h&)K}@8Zpsm_L>bZaXTo@nlaF^V?A%?xiK826NS)$yP(VNxwqQzgO;o1Y7H}JyPvaagrZnk|Aa(z9C(J>f@&wU9kYU> z2tcII`E<%o*};L>k$|aCUK5PxORUiZ_7Dd_SH}_=RzeY-;X`NJEFt0@4VM#hrgzDK z%O;l7(WPiqv2+iS98@L%evT6$WO_)_3wzjPQiXqEI)@)*l+~Yo7-664xj!r zKu92JMf0DF%1ZRTQ9sq*KV)%3@xcDpyjH^mIaj(Clshz7U=jgkW{Zu#H&G(k{BQi* zWyy4QLD!TPaQDprSj+134mwc`QcK+l(3%;ncOCANLas}`DrH%S@?XRg>hLi0=@`}A z+{|*NhYugNKX|o2JyJQ4@q$hmc2NW#u-#+)1V{&C>mPVH{Vk`G^QPgs?V?z7OPv4FNL?0y|d^Ki_C69)J%$=)iR^iEgIpnjSp z#?qTnz>r0;=?rXp|64Z^@LRL-h(1|)R-k7P(o>~pqajwJOATB*y(`Xu!8a6pAH$^2 zU5{d>Pz;c!5Ik`Mr|BJJ|M!66W$^6(E`4agN=_5@*Sv}C?&iJkFO`SsT}D)TU)UGb z#G4_36P%~0XGP+9?cH2i%eOn4^8c%(qSB{r4Sax`+S_Mpkp`Cz_K9l?zGI-FW$rKx z44}duo}Xm@e5d`;aY1jC0(&O3IWQ8*L6a&z#jY&lH%l2e-jWP+Hbp$2XYf5Er>(H= zi4O(gMg8qnf`RYK6B-+L$cfFTTBT1SIV1h)Rdh4MqwB88Lf5NOgzK~4p2#Abs&5xl zL}t=IFwH6dvjOzO`0*5pA~d9SBWcr5Z)|ktB7i?gUZLg>!hXuPrZj)fvGrIG#RF-2 zDAMkzBH!Yt0KBh5FqByh72;@31KJ|bF!0QBJQHTMvvBB*|}(P?Nv33QrUL(<9`>upHLJ=2|bCw zd!@<0n*G@w8dCyF4Cy(8>!>xIuwDHtKpgF+{jk`%t1E7>B9uCW?!JfYTK{_~>KZ1H z{gjo%MqIt{cCO=HAdV`r+oX@pVp4U zsaop;ISL|MK+jnzbv^fg3|W4A=yrF4Amh$6kAR{GQ=|U^8di-s{_Ym2vD$*n@NchE ze{rgqHV;s!E(^=Si_@pnuTVixl=ZUyk4=H&ODse~zM~A?(KJTYXW5;^UvC^&POkz~ zj69zW+%iJiKqiTSevq*%0mY?FbHkB))UvZ!-m#s+0HZhhA z@V|n##ugTC;R6?cXJ}f&AQX1Gwp+F>NqEQjazR1F_WufN+z6BJ=1XvNm}_U~SxI3B z`bx~}#34|zemJY3D@BXes?Q%`O?p<|%t8I8?|!#$LjeJUs5cf7Z*fos$5-cMPjOa_ z8Xq4IZIRp({wlkW=XZW2c^t-7I;e{G>t1c`A2&mHQv2xn2IdDw`~UJ5z~dhDSJ0PT zB?L8oFglwCU%N~Ij2BgPl-hw$OSWNcc60qNmYA@c4&2_X=>rp>R@2Q#sag*B!51H1 z`x*N)5$@f{KP;3ka;(paLYo?&cfMXRey3%g4s5F(9paV)51imO_)km;6v_P*vXtbu z3Mcf(s;^-Ur`X_%x|t84s-9l5MdGlR<_DHQS(xn#@u!Fajc#&mdK z!W*yWx??lThlAU@MP|cdk)G?uX7p1UAi~Rkj6K`lPx@_OOhJFnB(b$-_ypykEhNItmMuIyWG?&4y-vNL7&F>i z?A0`;n3BCFUd@3fQML+@b^+UQZg14#8e@-HMKy}Y2wT04?r5xD|M~>vg|I+8am|b4 z0e9V}%wia_gvk=mqGtFPnl~Qx<)!L(-#hY^+jZRW+HLCiEg>|Urd71x_=F?fExuUt zxTU@tMcZU~WB*_oFTwZxY+CQYQ%Vq#otJm!;Ls?X{Pi&&(}L_R8-V!NO7pTl!~1dS zXd27B&ahv&I+A~BsnLtdk15LSHi2$h)3!9OalUPPbES{LCm6OJm`O%PMzcV zdF%afUJzC426qNC*%D&iLCk;{m>rOw`#!imXc;-qdppdhNX!uVV!BX^4He@`cCA?2 z>+XR1y!{vMPis)|+^X2XjuTaHCS{-qy64PZ>;}JhMl=JWR`F6o8Ad; zvDcS+OCi0vx94wIz;GkuD}mC*Jdr!u8tgy9CSU#6-z65G@^w%6epz7 zjn)D1;5^-d+{ozpi{27isjPpdnA;iI+ozj>QMvCnWc)K5S&;6VXQ^Xc)O`S~)E@!^ zShR&G3Q(3?*tplWKX3_w2j=x9r?OPh-RLkneX;ofb6cg(&e3m;`RyiVWRoko3VP!Y zac{D5>8AJmAP#2Vmk!!&=0iHJ-O~;YhwLC)b6X({HrzciVPB5oK`Ah7E$Fp5KHua_ zPuyjWB7Jc$N-1NF9fe5A2g<(3j9v~J;wlFSVWd&>$0fCErcohKepX+^M|5$<95BZ( z6U^BeZTaNU!C>lVSMS{&eZYaA&s-vdBn7PR{l(1*<-W6slD>2>eT4H)7wS=DGrduX ztJ8Q^2KYSGcAY=}&SaH&&ppbNr$9)p!1SgWPy3DvO&Ht@@n(DU7Z`SI@Z(+_bA>$c zax9mN3yrOU)emWQAvrmn-A-R@if(~SQys_%bRDl9rIwrtNhA1%A|db&$zusBKlgUR zV`}2Bweau+Ep6@8ll_zpt}27W9QOZb761zQ&N!#}a;&CwyJ6vQD81N;ej^LL7-ToT zRf^7dOkJs_l1u!8mfJJTyz38&^r4hN9C@$QE`p~3aE}^2B#Vs4XI<8g2OG0X8GENb zQqQIzZ$}uy3(m*RdyL3>lO$yZom%g>2?@bJG*OTRuQ&te=ka=a-@%H5z~a}k&~=9V zLIje7TXiaC2>=O54t!%Uu>Xw5EM)^`m8RD+0TprI>DWM%e>R*Da{NptxIXBXpc(+N z0%{HD(L$a~W1YZhSA1gx#jW+%^a@^l-liJ!SLY6Pj%T2n%q{=p`2vY&RmONu_OQZv zEXnwq)=Mx>tNV8-(Tq<_*yckVDezr?ZX*3f)z$o08)E7dk$+T*-md`WA(WK0(>yJ% z2yIbuzku5so8|zP!Q*`#$~_K)pq8pCc`@;-mg)DT=n(9*;T@{AYo&9gLu7dKyu1yJ#{+1B5WB5Afnk%D>N7UcvO2yW$=f`CbWPjEP9qG{ha({< zo0cy`*q*WmaiN5sCsq0l#h`LbC^p*TG;YGfYlASPsTrk~2Mv1`ym4|NQ^%k|ZT14FFzQA(v&cvE%34`W0Z!A%V$%ke#A}>Km0YNd94< zm+9k|2gGSSQ?L=4PuJ7$yVlZvNIlVt?McK3d4V!qm(N-RVn5{4+EJtm>@m^7ig(=75Lz zl$P9$z4Ir`r>3v8xJN-SEKh42H!Fz8`Mr_*;oiispnlS3nJ0OM0PbW6m?0=;T_%PG<`y4*i-rZ>ek^)%`YiwRR|5aLW z(*@>&A4PhSbv$b=se;TLCH8c=wkl;DHb(NeY9Gb$8=C^hnl}UZBEL4R6{~>D)TRpz zVB$P!6XTEnnPJcGy+hKPgSD|>~5~lMRlkb4sF_Lkjp_b=^ z?CV{MdafxXBGy<1h8((bHV#f&Rhm-q#TPPp4CQiw^sKypd8Y6lB;9ENtG_?5`c%5u z0srl-C^1`86;hbHh}}#qyfJV5Afr|A72`c!c4lRuZB_U+3Th%VHPbxBM~pvLs%wiW zNk}%D=fLF(8W7LC%L&$8>{tGy$ONPl@Ba6jD()zrni&T4FQ*aiPA8wsJRJqMsod?B z8tUc;KMd_4RVwN*Gxb|!^agQ7r3h^x4LqTaZLOwz{Uny3on(TBuR`Btak^xOTNyqE z>NWE?wByB|+Y8U7+vcn8IPaa&)m1a~S&ONssnChpn#GdSPrBZOGSg1@q-tGeeX*4P z<=^8`5*&`2HuBy5L{#(q{1_A9oL~nh)35HXA)zuVV3-Gd-t!$2?}YP`O#B~Vok5Yq z-00IFtLFl1$2FH*$sigUy2?bXIW*94a(hrUzdf;>aKNIw5rTQo$Ljd0{dLe8 zL3=MGm;!=|BB%A}j_%a#ql(S}NiDuHj-eE-ZpYULE1>y^b0H^b#=ahR*Pm}Zd3WFm zVo%)FaqBJS*8D*vlka$dS%qhoqeGoxwByMPAr3wOL<&elcsPf|%8Uz_OZkucKk&Td zTV@rInUmbgk;Aax*p&l|FLQa?#pkTX*LhO0t=spw`5yu>*Yvv0(hV$~^4yiIl=1D} zorV7Oy`#p`OS3V$gK8+m1B@tmMDp)v0Phu`T`KbQy2tiFDYsV#LuO~pX4>zwar(vp znf;>>I+btxKPk||i%jjb4F>CZbitWCX|HaM7vzC8=S^NiO8z9z!JS|ul3^baU39%>T!J84p0yCY5ECRguvzgEdPCHICQj&^ zii#TXam@7677)2&*ZPvcKmr665zZ;mS;1ZK^A|f90chu6)xiXr)Si!Da}SMd^e05u z%A3PAX|#Y0GW$W+N3m-is=W4S^l|WQwZ)A8Wg5YO#uGE%go8e+l6UK~jnjrZpac3H zko)}>VA<~j$>i7U(}v&I*oR*qdoD8I`&3Br^8wWejgh~Qukrz7>O@)3XGtJDzY@IxMrbcGL>^vnuls=zo2}THCmKsU^qr zZeqq6>C!j&{&>2WwhnbZ8Mjh+REq`8%>cJeVF`eZPOA3#Ne*c2X7cBXc(MRyP~)gQ z^wDIc{nl*(ddTiXL`^qmaMm8@4(rGzV@zz<9{xgh8Z6F&o6W`{WYs-yyggn zh5L~S#wqaN>x1hc6>6|U5STG~Wqzoa#5!uk!8`k(bxZ>JAs78Ab!6Bi@@zeO|I(Rb z%mj2f9F@h*jYeTI&r0;0Go=!G;x4mda;ZY)sC^EvOsK!&4}LWF*0_bE^KxDErI-R1 zqV)dL5KmIY0`F)G-LT@dtaakj`1+YvY9%yJ4-=WXH?k?r0LEgnd~o=tJ0Lxrs0~?Z z-eMBobp-)?1zL}3Ztd<+`(LsZs(?x*R{0nrKUzxcIWFC7sm@7}H}=ZRa(+Hpn#U4J>ZLu%Fk_l^}#Ztk=GF# zS#C$0iT))>NrcP?zyRN%Jkvqq{r3NdE?VpBN$B-80-VPmM0viDka*d3$059d)3dwoJ;C+l-}YvK3-d|)){o>8jw z5)SZy-GmCdJCAg*(vQTA0d*|vo6~t;_Hgc`l{EN1G3EF+N1R*>YP8aQS&pL1w&uHz z2R7np%}SxFa}GB=T3tQ%eWfJ~nyr7l3q_Gau6P)u8ZTRmN+0B-!KQ(ejQDwOmXbVq z#8np_(r~V7n+lipZfLA>3xUf%T{&=`t92OXskR4QyLUF56Jmr`B2}FYVg;X=V}M{E zD!AQNdasHFauI7kT_=g$@#~86bJco?h`DuVtiKv-oY%3#New@=xZS`WZpJGShN8z` zuiB^Dx)+|x)jzKJ9SAwBPIaNgYNlG!pyo7CErz!_GG_*t>QyNzLOY7577s+kDriSm zB5_mKnXlx{3y@nJl{r|W^x|_<@nq!0C*Ws&$z}aMK+zBIk878K{24Fk_mlOJ58k9~cEm+V$$)5qEHGP#< z0!|O- zotdO-X;`zH_CrL?TBh`=hit;jKXWZvba`zD1Mx_$u9I2-o$rPZET1 zj`}mg>n8PEYaWc7jMjCJuENkAlnYzUSU0 z*^Ph%Ev+YPWgfPS)ATnSzd1PkTHp(2pw;JP_5`}Ym;5&>R>ps*tC zvQYXL_huBVvz8};pWWk>G_rFwr!|u063Cs4hwJx^N*F%j=8r|Jcl{|t!*WG%Cqb29 z7=a+%(xD|_0BWImXbMQJ-#RwmmPEFS1+kKs9Fg;Gl?oF{spr!Bqr2=vH(bsEkRQ0#iDHonm)IZ7eN?>u~W|NAE6JZNuQjWqdUrS^uEHv{(_Apr^mD{O@3 zFx+L4vyc$>HAoGbtlR@qnMSyUGav&Nqu+9l31Pd>&i;*RUrs%lD@=R5h?|(Plul@P z12xgV&K8p^84ox)i@~%g(Q3Lk`LQaVIz?1E)TN_M2psO`U~<~;-!xGK7Q7Y}Q=kw3 zi)V9!hHMbVksD7fXs_=t>};kbMH#IG!&=?`S`0`p0vuy{5qh55)GP>&e^(CahCZrc z^8IxJj0^b#iYIf^fyS4~tfDTs77?6BC3_8j_?Hq8*{=)K=5~c0xWn36PfU)eVoj9-ZX4QO{0+<)4a#Ll(*gi(1dbx(2u4_^L}6B2x)fbtj%=kwL=eb^ zK2wG@_Gp$^{=>g*TJ%&MG0JFYxxMeLCrxm|L zxE}purLN?w4Rl)JnwA=U+&iRq9O89zvur--P~J*{$S~l$evb+W6^Ee=ly^MzY6;L z33a7KnvZjXic60|M5*U{xh7{WVWti2VkM7nHH*~2{H2N{@y(^WiEZV!jcE~VEkG)Q zAw@H+1FT8-8B!LqD+M~HT-vw{jbVg&3E;F_n%z+R7%i?;!S>FH2uHa*-T1LQK7Zc2 z9L|KFRqx~Lm69p;dTqA{1{B>WqQ8Jw#8`eS_;4krZW66{vb4||DO%UmB*kHTfzN^8 z)HoF+eK{wr{V6fonqKfF@`YU61JgDAJ`NCw-8*QgK%*q?(U?g`0%r$TjFRQL_l{6- zHB?TH-t?x$&10+4B&XdyBI6w@h(|!|&tg&23t4|vFv;|L?dGBdp_J*e28N)fs_KW- zfra^4`a`KRE7Ru*g00oi*XCg!72<=jMY}h{kM`wBK(R9413L9vhp0{*e)hn|!PY_FKN2^|Bb|RY_V$jl z>QP1#W{UYf-dBD0?mP7}h|5N%`jE+y(}LSj;+zb`KD!Eq{|tXL*V$B60`-8WS_Xw$fW$U;B(O-$*FJIJ4@96}hUOMeG#L@k9gNaZPSB#Vu zL`jttKBlg*psMT)Px<_lcQC#uDg61sPTs18WfEvyDxl%hM|=RIQm+FC3aS`$>yzE? zIObt6)I{mMy>-~G$F8P1WoeZF+%*g)?$k? zlDpjAvsp)l@xEbwPIXyFsG#+T(o(}i08%O<=(ejhnQ|dvp{bg=gS9=7PzI?1iXim# zQvTOac#~AGTRCIQ!5b@J2@?6eSIaArjMzc}4 z<)8zE_b@_317J2mjm~k>$rSANgTl#wFQ!nq-|JwgS42|Kd_)PB<}k*2Pn9h-6P7k& ze)?EJo{_KP6Swj#cZX90cbq`5O3I|c=Bik_XPy`;=D7_CYkf&6?_mKrJIl@SvS!@0 zHg2-U;Va%QA#h`T>1Oi@`Ty17aPBe!-2$%){+{E;i!-e*QbJqJv2HShxtOsU}`E19SY61m+m$ z`}bhW?BfK{sLm8RAd$?;StXZIp(iMLD%Tp!3Xq3>zk(hPSgOlCJI z&#EpuIkDV5V5YD|*K*why`w{~RE{QIcF`Sxq zqTf>AImDJ-<8EkIY`cV!ZT}md)x8Fe1i>}m{ZMb)$C|8m+Rb+dsffF>d}Y71IjU|NCab_-k!; zL22<|Vus}AhSN@JvVm@&FFLscX5(6qbmHavWtW(bh7ibSs)sbyuYWtg2Du_Itf))p z{T_2;@04*gJ=Vh$7S4qq&&6vb@?Ne5mZB`H!tQN;zdcD4-!c3k&YU2eq zM#MS4&M9kygs%P}i|mYO0--1&Ss0;3J=y%tDLdHu6(Q55;Wf?)fRnThjEq=m`M7sJ zGv_ZjP6SK2zC`c`mZG3sG3A*x*|{}!U2jZ|g!>wlDQW7K+SLdjB-$BMgw{LplIu9_ zugk@Pob?=BT5@0e%@Vl-7y=|6$Uo*K$}~NpotWPep0D%!WK3U66N=I!d>W5k%Vrm* zaz$aH%u%5O#x4#@NuM>{Nf}_rzQ_gbd<7_ z9bckEQN7}NMK;YF@QaDu33Vji%ymU!y++|K+*{|Nvb1Hjf(bm9`_dO)a1UkCy1kKIo!QKhGo6*)h-oV~$!#aWa+FBE&FKoMjA zOYU{OQ2LVM&{~bR3Y&eTV4kb~m896mRz;%zi-YRGsGkO)%qB3Dl^v0FpE+3L1ShwP zQ4#&Tlo80CpBLMx2N>91t($8>WTVwv@mWA>-WM);%Um4_a{tfdlL5#zGmoOuMGyOKy6Etl$?@(-9FQg z>30H8-lmXrEb!_q?%xS2>#gnfq)VZ4{euYyhdH-Q^YA&Ei$X8V*j7LcLjwwX#Cs#% za#}zGiT7Jt==t;13EY1Rrq|>jXpAQ>(|xn`tLO~O<}Q}LJ@ITgS?GS*cydyI_nYnr zcMs<&jaVF!_v?az%>HP>*GEa-%EMy0tc2J{OMls~YjFFej=p1maOZ3kXqvZq=Vn7# zbjYN|g=KxN^!C7VcpN^@S*T-9>#&t{Jk=eoTAR%wmH&k_U>bfM3iuqp1e?}{+O&tQ8d@?y89+|+jeK9McpT>2*b-a95t zE{k(XOLfJx23t#BU~r@}<^4vt%~U7T+y>(w?tA$5F?vGu*Ce5@+l%o5+ebd1%tH@G zj9ou|68&vDywUsPlAQ7VFoqTHgFY~?NCoWyxbIf8?3}kg{pXEe;mW(cJ)z7zl%MJP z;A?Hf5}ms_GtD=>aI|Pb9+)Vop6rZxReTxl`=+e0xax;LnaAiEY4Wyo^;L}IwP~Xq z96Bf@;kBeV5vP7+~wSf>*J?YqLBuATc#EQ zQhwn}%I}^Y!~o@_>^%q7Vi~VNZ_zfy00eLo|MJgCrgmJ}eg8c8Y3%v+0&3RwGvbA9(+&B~Nskag;dNW)+~(eI;wDNt?d z(1}n5DalABw0zv0%8raO2S&9^=kG9T_G`Vo$M)uSTQyOD6tD2^{b__05F(Td+Yh~0 z+86Cyw6v_#jUtvjvqc01@ZW1+E2|R`5xYzSnN%;rbmd@m-h@7%zKyGRCEgs| z9kmKHQ!X4B@bf%Qy*9`vV36FMt8$PY@P^h7eOIUAc^M@CwkgmR#wg{h@qd=!bie$H zENIZ>H!(A*3wdspGA(bIr}CO~bN$7*-+y8GdcA*52;%TMiM#HhK+^$+J|mq&=i?|o zP2HjlU*CsFB?dTRpART{>saE%@$I#h)kJ`9oSn^8JndM6;=i zlflQSpDQw+%+n>>AqG^Mujaf#-aFBM1Pi*$y$~XF-AbN{NU4ICOl{09T@Sj)Q|Gsq zv3u+I4KC~{CE-bW$G+ z}wSsc%x5S@9<~w2^hqX!Nf)yr^8j zde`^=;_k8*u6-nRaB3EecwAv$SFFQtG%;hB2l}Fuo^|6hC$^<^<*$GcCJkl|cJ4qC zi}wG2IrggeupN3HwbrX@{79;a?3%n_r#icB-P@M1bD+8}ng1IKJ$JC|6Nu?csyD%U z{1_?ompf8sfiR%$3c)W6_`lx^5Zkx|8ZMrPesTvk6(}DnF;2t z^EY z-^+z?clU6%+y3<~t*Z91*uBoL8O5`_V`K1&CL>F2JV<-B&5;5QirsQJ1i5vd543WX z3%(zeUQ@2*ltSG~RP$$S{n+LJMRcmyqAposQHk4{u|e|a_FW3G^UvLyq9&3>=(jfM zr9C^NbhJXLTNLf!VyY|Z;w=(S#)*pf>q${rv4(f7j!-xwNvpGStW(DVpRl(lRvl{fUNT zc*JzYx85S9bqfcrXWWMXGUKxiKKS0{`1|yltr9z=F$LMz+$Jg>qw=|{p;HuT`tecP zLcW}w@1Od2uk%$du=)tN^+0poQG)(ixMDEEiiFsF-9DmSgY)s2Rf%&6aL-evd zm$vUoAQ)c+cZnhML5)Cpt=5!8+3BYk<6skDY&P9} zcyj%959OS{(_#0;p%UiwoMbg085)(Z=VK(wtzRmE5YI;ARcQ-M2{dh%B8`56;lqvx z=dD6a2ZhjpEbusUuX9sqfR+NZ46I(&Pt3ufvES1%HMzpq+Brp8E#A{fq_o3NjWtZq z{Q?-jp)h9^KP!eApWvNxhrKExdhbsiBI~JF?}1$o^SEHdkbw!p3Vf{O?%!k(uiu+x zW~d(jsK+p-ap5HfZ;M*|Uetc*RdckXz%s78xHjjnEFm@ro!}e@9q?yMP9nav?6a{M zx#wgW!5XWY{!Ya6Yx%Mk7-(bRZC<6*R>&SY2Aw3E)*uxex^m}ZFp%*%9IhH)D9n$g z8zL2bq}GmIviSPCtE?G!TE1?0Xk;&~(S=<6DBtTsQ5c&~4wbL9ui?9z=Ilf~of0Ok z&sT*N0}WB9AX%biqf%}1nCrAPJ>qnYPEW+pO{=Mb(<#(BGJnOnZVz|TDP7xq>(@wa z!0(!%s0fP|3ft2EWsolWQ}5VLksWinv$%Q%Wmc0uDcl9>JG@i-6nngh&}1zJRrwR@ ztL5wqC;QXzk$kiIP(_tc?*@~ja&|Zh&^Oo7?i%AneQoV?8eqTIxxv6K{ zc2mt&U3Hv?&66GAPH+58d&&IswSE69qhZ2rE0_xORWv{cL{bI(fyh|>rXyuCKD|AN zr(b7pZ(wmvi?vu@fr;T@nMOgz`*QuCax-mIXFQnG7#k1jIJ?3RuCe{|26FP|5iH{F zhgW%kazDKS{5djNOptbNc8VIAVpKkE%!JjZVp2N)ExPMI?CxV#t_sT;E zRtmIS_p^BjVLN;hSRKx!o}?GBn|1v$x!I~Ehle*_&DB}de2sr1285QC^_fdRLh5f45p zseJn%*}hM-`4e;L333f`EGtvUGHnEAMbd-l&Z=b5i|H4eK0m0L>osDO zi-gC5%dW)1ch>zg?Wa{h@3q?NC+_&F9eQ7e=Q#M-!8s|Qsp|o=}EnN>rOL;m%d=J!w$xjNUkyj|vOOl(o ztNzZ#_xoq*qa~x;R^gR=#j}*5dV)Zsvp?z{w{IF+plTa1ruKcoYbiAZgS@uh03-Jl zQJs0<)~yy>EW;IU3c2%}qx)iSDcusWlSlEAgE@cl?p-{JPqGBL93i9;9PmTU!>w;4 z_qZpy(hSK4c)i}sap#ACkDnnSw?jtn-uUvp&qDA3Ts>~qh)gq+u7vJP7#p7~o=Wi| z1=ABP)5PX8W@!KtD3a59SCC!g;pRUdx3Rbn%F8vK*L#I0yYQR{4+)Kdiq6^(YhDA*pV@IRmD26&T6${=tuBlBoJkz^5S+ul8P z>?ZB{fevJq?aqM6h>85DXq|Z7LUc4ISYj^TPx@hHq>7s|rx5S1ZyD%f!fiK_S!n$h zerC<^`s^c6PJpx;Fl3__5` z1tpb~?odEbN>EB9lq59h9vZ!gGD zy0s8o&P|%EGq{VF$sy=v^7j>Ce)FCxpLR6WNR=e|QgEV0iyZ{n;e;qV%~QLs-3PLv z^hmt~&AF{AJ>{#6+zS74HHEi-+Ps%bvjD&|r}EH`Gn3Cs)iw)oP3^;n%DU}PS?41v zZ}u;ee#~GBK~j>*0-h0QATQBjCoR1ayGMQB+$zh@Uey<5P@b0oA?oJvok01*PEP#W zeWJ)v9OJ7OjcXh8o_l>7qtG_`4w^>2Od2nDw)A;8p=F&a*m+aOU*2-KSBC~wBcHC?t4aGiR}_Li`Vh|OjhVu<72|0 z0l~{V9saaY=LIpB#|Hz|XOBzPs3RIA;w5#i%uZ&N`TyF6o3oBZS^u^@nz!x+)@y-- z(rt*qval7aSwM!NfS)+eS8UGH>it)L|9MV7vku-T)9di-bf^lsV*JHiIG)~`E)-sS zb@69EK`}l--{_A=HB7miqU#hsi#^S~Jq(ZL@3-N7g=j4x4v_9KN%lGdcxDKy1wd#h zoL^;VN;eFmHv3WG1kk-?@*p8VVqiwv{IrE-J$IAA?)YU}A9dED+p}9cX#DKI>LPcIb zD*3IIJsU3E-%OrR&(s=I6>nsc6!AWDR)yS3xP!PPo9_)GJ(W_P;9_?+@bj-`i7+pH zL)25hHLetFx*-HStnAWL4`f5yQTf^eiy7|+EHVLgXq{c!?aRNN7gP6ge#v!Cj*j+s zO+oQ-8tx4x3J z%g}19d^5QoOi4FE!6!c#su_FLwfk~IfR9hfc6Ms&DgUs%x?yok|`g|KzQ+7sK;I@8SLL>Y$Z1 zI?xk6Ke$|+F6Qv`QByQmO6z+iAsz%b1@Gz1UP`R7>UonzYj)RA+CT;LIK|n%3#=A zY+R?Oo$*sdN1Ka#ecVefuKp7h`=D6T)Tbn}nau;t&@GG^sxj|tw-SL)$pCf`0Cp&? z`@Sl=3uhUQo99I1i?COzBGMaV44Be6gq_u%Jh3RJ{^$L;KXJ>v_czzCh(xDSTei8} zp`nl)DgkS52@7xBy=K4lV5(u~RIVw~>>&M4*XiHAZr|0opWh5xOD0Yx3gc=u#CPFI z8F^^#_GLLdi05sP28xiImp46k5k`#y!Q4+*yp7$Ae9LVyB+gFh3Rqb4zJi|W6?!h5 z`Mbzlv%b=doyaokgG_&gztBV1gVrjZ>&26cEC8Y({adOSgBq)SZv(iI)BX}C>4Vmy z;Ruca4Nnnza8YK82>`0FE6pdN@ISO%4j!IusyNb0G6={K=nG>6U9S@%EI@YRlkJ>!Hz&8K(qV z0v9%PS(7YEdjF0d80E_A?(Q}ahKYUo4Iob=`oNeTiHedC-tPN=B-p9LCcNJ_Vr?qd z+TW|qL`PZkZ5})Df+k8W7y1?FFOwbq(nPbY4#nNuZ-KKk2OfD@S^UZeV<&k;+Idvv~eVOOhBSwq$qf;K6>mSRbY_jVb&IyTR=CeOL+&`{nVl zg-`R7IuCVP3=v+wsKS;$@wu)(Pnd-x=Fd@U_4W?-m*D)q*m?`4I7a6FqD$5B%H z(sNq`>~-TbU~oaVeoyjjfH!&XNGlQ8P}%0mjhtr||8ujUfRtYf+Wd6`wqF;c65YAZ zXab${U{DAt-lq76MYK7=C#WU;YYKXrF4tyD%tRNZb_`H=6ZeU! zYlGzlnhjq@J?cXRVHi`1_<;p|7=A5_^H$n06oz}Z^PUFv9msmj*$i37;&CigYJMsj#1&?I8wej?dhOfj*nB=8kHh;Z4bI7#czt z8gaY_?4-ITt5o6HE{$3|{PX9E>V-#@y9b*rdo1f#zy)qk?Np&38U(|BXls#@Mm?6?wRo&=a-toN){x z2L=Tys3HDr*Pdgn&H4*!7%!|*dwocNdxQdQKmCpuDcFq$Y&>reSacxdxy15ysMg#U z`Ab1$a9uF__2yB)@0Hl~l}K>jQwd+3$DS{rJY3+ZA#G>e{;MakRw)YZa~gAyq~-j7 zO5SpHEo+l=>>IP3qVJ`brl1e^&U)Wtnn2sh%E7GGGu4A2Jj2|C>DkCIrx<|6>0eO% z`#LYQv9KWVJ*0XBI>9Ikb}NO1ZX|2$9K@Re5;-|`o?ykquI&84m7%@5I$2nfrHqWx z=yRm-5z7z|Mk~Mt^d~2emjPUO8*x4_BdV`6|IUM)WKjHqLWGQq)(kG0afS6X34Z6( zMw-KbAQx3g@z-T_k|Ldx3Ci`$3a|jOX$-`f@d52@N_C`^^fzF*pls~AJ4KNbT9 z&pF1kAkba7ECPjN!Ns!t=9ZHcGRBCmx)br!Q%b-BZNLJ{%-rrXfGzGx<2tB-`Nl(? z+%0Q&g(cMnf4fu^|BUczDgbtsCmo0*5-@=@OyfjiccFCv6kLmqz!8j(r=|toRPPru z+O<5ND;N@NK zHUdue;fe9tkC)M&A}rljNm8IA+&i#MffYl|V;oFEMn*7*vSpoy z`2>-%yR_InMv_3{KTG2B4_8>cpt&EL14<61oy=l^Y{O$4&8KayhYx9 zW-kbTOFr*;wpdzMHv^#M|M{phZ{KrK5I--333fu_x&BTp7Jt_Iw8c1G`JnjaJV7-o z+Q;bHTMMX}%vbMNp^b?NFyROhG4Arw8n|$8AjIfbd$$_7)5c6zJTSR8UnFrWo4~5I zMFOL@l=8-SBDLPB4!D%zCKc3mquv{tb)Vx$N*-G2?3L;+hHsiyi-*z=Ow=EWlj zN3$Q%gpaOAtGvuNgyHkZM615ptoS$P@Qk2@PutK%I@R3Cii-ZMDWZ4Ar!#-ztMoi7 zGg9mfqHAqr)I{fCJA4LcAX~d$fT!$&7c;N(Jj6d|?TnO!*v*ZF$}yWHC5vcFgV5Yr zA#J#M@elBkusI)_%tp$9Z_Jp0{T!c~^JcgK_XtpF0>YujYuq<#z55d%bU=*FWHTak z>*@C7+7!U;)eOV!TIM?OF|&0qQPTZlK%o5@#YX z(EdUm%!B*4_x?EGG;gE7Bhpp6g8w%e}pg0bjGCBf|(d2L`qblU+1DYl;85$jGz0A6fLSDdUiA^%Q4_5q0# zRvadnef$P_w;D2#l2w1uFES7+LoWs5%G}IMruBNl%ut{zb%DNk#rUMF{fH_2SPrTR zO><4$!QbwwvkP~^{j~%a4vq7(vAEm94ovzj66QC!F=xon-I}ggSMdTdW}QD4bmGU~ zJL1uV0xzZ)>Ev`SR|ooZ!Oi%@Q7xh=J6~jxdB7Uy(eYp(fVu>`uIn<9Y~q9#0(+MV z2b7wA;Dt4C(7i#1;u+J)#1xtWL>f#rV2>U@a*BvlbnQ3gpB#7`g!qGyi?H0#gWIQ;xpEWHSR__g$Qw{UE*X zG*Y3x@_aD_8~?8+w@DM%>xaT|A z!o^S>grCI2Bq^J_L19!BS}D-*dmk%#VNaeYTfhxj3|1ZiUf^$k&!W}Q($uv5g{j+U zXuu~BR#hFqnsVv`{Z2=#G=CvFdySwUURn8gfSdU9ea>w7^HTeQm~TcX{HHbZp3OB= zM7BifQ12hyHvJt%#zyVpm~h1D&-TrbYh$4waD=g;;8sJgPQn=N?F-tcps|^0GhkWA z(})Dk$a)27P+B)kkQm=kqaTBSAvp+ysmbxBUKySTeq%7Vs>0Si2%wW@+8(4 zW&I(bXj@(dT6Ou=GBN%LSzCzl!Y$qASi&vUM;os3vc zP6DRSkQ*=+w|ru@QBza=lg%xxi0Zx2Te^B01LjNpJuL%f^`%yRQ8cIYy7v+;dX-)xt>FFb#gA<># zuilHVRK8H08NxL(O6IJq8! zWJiJYZk$F1HMh(Y(_dco42_sMf>4`=OH-BQ%en*b2`n^4;`>d7e#s!LFvREzE~UKZ zpmpc%)St2LrwbJE)_gxrKQsX5k_`I00Hld`A#G#)S@k@6ebhp`#QiMy;+#e(@()T< z3>bdcyYa%sj_>%@TfOLru#iQW7JQ?olD_NbqJFxZ-91(`?GVv^3i?DsOM#YBHV!tM zuU6BGHtRRLoS2&gL5;}9ki|g{TTpXW=&y?k!u@PXY!()7n4l$-8QjpvV`{f7kp0D{ z?4vmNd{T9}%t7WlCQzme-0|I^;wM5$Ee-K z-&wE@H~DUaav~0hd#+Qv3%|S27%B$)_w(Jew)=tXW&DD%G6(+wp?!PDn$S_A>{daB~1b=(A_5l2Bq=K+z zam=f$umF&V15%rv=$Ke$f*!E2!CPJ^LBwTtbv+@Xx4U0l<$sc~=rHl?Ua2XlWbM)u z?41mKNpTXC0;;?vQyfO7oSK%F(4Ef~BqEA<5@*D|aOMD+-e0a$USC^Z*8!jv_0?6< ztg3CtiF<&6Fh;_L7Oz@*q%%Gs==&xJ#U>-+4q2K;f3BjzZRHl)UxT$sO;!|)9Cge+EgG|y?lpwiqF{AWGwuD zu>iu3_t{5*oOoj65|nGB2e;S^6kZ|PL(I+1_n8$vZ$S9?A34MmG9HI=>Y)G~RvQZe z=RtNjpVq<&_1tQ`!`q_9oIO$GUC8F*!6ur`^5et`F}UYI4Gluk6nQl0`*=Hoa_)}L zzWoI&@(1s)9Vh8vk&UMIVr0~p-aYmN?Ij` zoxl*on!hGGC!d7wU-b1x{8$I^zO&jhL-A2-Ic92siMrQBO-fvUJ5$AKlR)uHtEBu+ zrIlY}e50)ouoWD@R_MGqAM>ecQ9_9@5c8o0tb4gF*iFKElNjhOuh1#chzku<0f?Lg zXXEb5ex_nP-Z(IvV6$H#6mjeU!f!cT;1xLn+u5SatdbL>j1K<7R!`mIo=zp5i(`zrB!X?PyFV0iplzGG!L>G@_3W`o7d z%t1uZv))2ascjV8OD)O}GmdpDn_Nal1_tVF80$YeI_frm)bxG;m@ex!Z-SAp1I)?b z6l9=o`5e>=G#b;>hNZt@IkM8J@VFJ#10lwiTsuAP30vc{npy$dd#YH9vMDN+5hz*U zgsefSV&vt3_@EXjm}ncaok@cw?0h>TGy9soY+#s<)c}+Q@gdv;^e6M~CNC&f?1~B| zG%Gjt)~}9ojX|s$4^+(QU!$y22^Tlm2>hK`%5SAU8~RluH`{h@(AxGn!iZHO*#L4> zsGKZrFL}Xlq8Z(OKao8pZZp-Z;IUp22S*s&ggQN??*3VU2qWvoC13=4}IPj|a)1$h;L*&@3tceK1o z_j3ZV=L~QN+3EEs_woT6jnb|0>awn|`_H8(ShnOl4WcfvT)?{*ei(kGjCaTP)4zG2 zkJAL60$$C&kC>H4l(0sC6?PiQYvhxXehZ|gg(8;6S>HJaRIk{m`08Brd7>F5%mg5v z?#iOBa64WyO0bJkJt|5~$GTy85d-@Gd9oxF|M7$%WlyOl%|+hKCkx$m-N_wGv}&tT z-{fpjN)#WOv+tw`?#e`50-M<4G!PSvo$SGo&lV27%$I+9= z(R^Sl77==ko>xlbmbOVSQSy8pNNLG{;(=r!gHl!mvWePyz^Pzp)UGrHzF})iI>uwl zsZkbz{SR2X5npSsP|@e2XNJO?C2BN6X9MgPpE6xe+|0!x`H ziOT`L!kPjGL>AEMi&+ji63-crEfX$6sH-(Cpiz$3Li64qf?*;+`gB{Uht9Z!+9Rp)z48#Em+#5o|@j2Zhi>1JU!?m#y&< zCR0I+wj0<$Awjj1F+EHewZadWBn7PUmWq01>~k7Xm!Q8Zv-QW^mX%S){fG?x8lwPa zzmXkF3$u&kzYfW25EN``H*HxeRlfw>{$wRIiN|CP?D70xB53+A@-l4}xauOrTxc^{ z{q+iSqhE{uNBJ!p93>*ib#j99!`~#3FW}F|0iw2#qBA{3p z%xqyOF6|tsC7V8bZ0PMuh8JrFzzC5M7VNa#Y*nDkh*+y$E+zN(AOA60iY+XVlmq=* z-d^*FY6gFN&Q=Yeg_lmE&w}K~LXrjT=#pg&89a->x<+SL#sJ8Hs!YvtyGSwR^66)- zKjGPXBgJv?CQ)RhdzV6x6DqDHO@vCiD9mX-FgMrvqH+GR=@Eu4Ab8l)%HsH}T(4a_ zi`8sXPW?`x>su8^spXVmBS7jwrVp-W%p9~UW{}nxAEB#l51S6HCjhzp7B$emfkH&d zp50C(WGUi6ned9)j9^Fk)X&gQy6(RPo?qk zBcjvajNR)p;p)20`T%Qgt|fVr*iFRCSpKH5R+p`~-Jd;FbASFu+~~@+BgykPO8A<& zl{EKJKm8ZO_M#i=8)I3V@E zC+jfIai4^2wBUZy+k4lIHD%(?)n<9eFh#}Eh4K0B@??bYWOVA3CF5JVRM;;k?B&2lo_tyKGlBPH6 zCISBJ&8DATm2lsa7SLSG$5(omH)K8}%+YtEe7b+~JiHzeP1$P3;eFUDKo00qMJ@}{ z<%yU5(o@*f=e)2_VY}$&R4N!)L5>aPy!BlY{7y$qMr2Xu<$j=N6L5vNK`69E zz7-TPOLMWys{K;?A+j)hR)nd*8vJ;Pfh8;=&Y5Sjj>=qcD>s-&&xjDPW4vRH8-hQ70#ev{~m-RsY z6}s&2e)Oq&t={j45TpDt@1$a2LMfk{zudbSuAeqx>~wFsI6iU2k6p_jqqta|S4Q9W zCCx5ReTLM5CNQ8N!oD}<#GX)7L=ZW(QleT>Qgk`Lf7q+95MW5I6fw1eP`|jQ#R;U* z%t*Z5L=7615J<63=(5~?-=Ldd^3^s8^Fwh(mhq}V>$kC{bM`qoo}J^!at)7;xw@b0 z<5;{T4Laagiq-nd?XKg(lB!2?0%%#)s1b5Zv(M*U?ggy%@m_cGI_ws^-NKf&`bTi< zr`CTzvMXVpL_ImBb=YNUGCV~G#@Gl~wGHBTTAmMOk8U*G3+v-Tpsj6gXtBJl3;@a^ z|5MG7`FPDhJKeAJ*+25z5+)(ty~_!)3`>tLXSwvS~$R-!(9 z&{8}41(Oe)yx6HNPlF4a|>5q1--XbPAo4|(YcM=%#*yeD~3JA);71~;Sb#rfkQz+B-!5t zi)}QojL1@qU|BwrpILnFg>q0BIGexO{pDZ&5AZ<$MfGJ_jt%WZty7*VlFYgF8uxgo z-nDP)#=k@95>)Wsv&OiCCpd768T(~v-z+URhDPrHQdyc{uW%FXTG!iLLBb47H|mw+ zJqV5H-#~6!-!m&UWzp6Pi9NjQj6$i?g`2wUMG2f%h%DfTE}!gsBeTSc6|rJ%#(%N*`1J9^z z%Wbxs^Te%2L2(@TMIMaVZzkawiX_boE)vt<-AQPO!i3` z)N5$6fQ2>h7^o$mLGMgssHhv*xW3?iW&VPz7Aci!-ir7#UO9$pCMaWw73?@$Iztnm z97DGR3D!5fW%m{Vwn}8FSVMY+8X5W_uTUxBy4%90MCc(^@1e5EF!8>MJ+M1biNZ9y^|0G@?0ap+bH@S^^FODgHIQT@ ziH|rD^n2YhdZXeV9B4&cQ2@?J8qL>g7MsGq&qlw772Tiu^pn@J)gqY6A^@L92D16O zz3%s67VxI{#~mfPXwee9I*2gHWWMM^WJxY0q(yH z2lfu)MCkfQvo}56YL6FGiU>AcMm8(0+^ij{C7--N#<6ldA4Yjs3Cc%n2H@h(uu(_r zu_g4l$U4asO`+$m3)hmfN(Uf6n@?5!vUD8h{GZctYXN~I9t~LLs98dT4Ev{$=e5z< zHOAV9n`@P9O!vhLOo9?U+IEbs|E(zB24#Rvt*T(yL6WrESFxL`aboxh<(eSDz#nW% ze@>Y5)E)AK@Mo4o)zWn*Y_4VGObugTr(Nt~yN0d}KvW27Bcz&r=r5q+Y9hDh7V~wj z7-=5crbosk&?U6G#4MNFs(YM#`l5j7NgPV182XCW8Y3cFWLDOKkY)hDSo5#mHvvOK zLn$!aq4|01YIYX7JK(m*s_m|q{AlYuz=qE{`aRQm`9J2%GE-37JM!J~f0%3?N5y)U~umms(hh)>A@-?HR zct))JJ!Aw5zHWem9+&2yb&mfB^Qw&BM?L$bDi~tpNzQx5L}mqm2_gITvV>H&(lsz# z?)YUv^`(BPBG}vLU2_G?AjYmOnqxTnhWTtr=EA(=f00ximp!Bo>^*S++iYG@QPFWo z^P;>F@Nj&K&*A`73gSs7*+25en*{Gou~LP9;Zw%5K<1w<8t=`S;34Q#CTn5Gje2+-Swu;e;+QHRjP&*PO*M?DgSloFS=0Mmi^5n;cefeYVsjPVEkE4hmO zz;1-G*AZ!akA9ZN3ny1rA~Vo&HSde((-Csqg%pVq`;xr%Jhn`&U-0z`NHnbBh9&7x zS2o`0yMIw|Q}4tw1MS7rQ3qwQa#0ah^?dNZl~&s8y0&}+X$DzrTBQt@!7gtQQZJ4C zjxXjx!M1l*P~u~S&Ai~-ovEZLb~%I4GQTo2J7AXmdGfL!E zPIz^ejfu$>XH~%6`HpN(mr~UFUVs~c$+F-RMGP>?0p-8gbE~-tbOG+WiXMy{#8}8a z5mQJKo%~o)Tm7yMj`v*X_%~M4bk?n$MYaU8s9(u*#Nn@yWQGZ^Ojhd#h)*8dB><=w z@?ffqv{=!_#ih&V@^z!X|GI8+x%p@u#X!zy*}eh}JGa?b0X&5H1aB~ECI-2NZf6D7}D zx8ZQ6VqJAGpD=2X*=3fha{V%Zb{(h z8sog${r(Tr9KclQE|o`@E_ImGh=&Hf@_yigVt6n?1fLVHouL4e0paG<0@0+Q)eEK3 zz~B@GDz3uK1WY@-`>Fc&VIx&rZs&*5P7-=x&nTh&PCfFEo_mtB`(1KBNDL@tR;JjX zrR1ejQ^?V2RdLsw zPsJJcr^RwIBn#(N!0!Jq3W;=6(T7IkTP!mw3!V2duj) z`@_34gWLbC!QjtNEpw*e38`QA2I}##INocQ*&xG)8x$0314bRZ<$+*nbFCkoWNAkq zrNU%$N5`gQ4A6D;U?umAQL|5SDGLh=;UMbWJD5Ir0IQt-r`BVWfK^~KUV?hHwDeN^ zzTtU9(Wtxa%^Xzn`7V4 zxh{g;Wropl7yV)%S;h}`I6t-K1i(uqs?k{M9cC&>vL*oP{Ax7;T01smVD+tRt`!Tb z*M=W$bV)DtWSLCK0q10*(@!ypb;*W6S=+1Lh!H&_SkDD zWt6TIG=4|N@^z+{y0Vgt?lBpT##Q*rv^ikc8ud;v0o?NxwDWP-`oOdXi$Jk9|EB@1 zqbuJ4gexI{VgH9B3f&8vEqn1057VF&l06qc{U>o@ZX!9p{3xl1g>`zR9lpXL>baZZ z0zxr1Sl5us6n+yyx1IWc1S{7niVgX&$pV}VTC9CwY_~UOjVdj%9M9MtUp6oYurK|Rp)W{0S`3lu2e*D=*I-tAAdxs=%NIG-ODe5&(4EDLzu>EEq39rV!RS2_@!rZ=`$i% z1cr6ZmY7uNSFj$4WGrJ=we_hggt=@7wei-yi7_A$3Ij{KgzYxpo|&E=R@6UhZ@@MQ zJqEfYw^5}7GDTWi-VJ{Mu;!NSqZatis4@s@+Y?NB`n5%^3(d{j4X5wGTe|Vl3=+Q%vhBZfQp))7 zyvdQuKIx{sgWRkG!04K9O}sQofGw52dv*xQ_CA#n^H+q38n@mqli(RdX=!c{kbSLa zzRj(k*Zrd?Nn^XWG0@amh-K8O7r%3Ffv+!fn1O*p)15k)$?fb2fEK@k?fo(`qFc&2 z@r}_?hw0V3I+bgc8AkzU7edI!;@|&&u>jWxcCtifdEf{xE;T)&V#m*5?62$Jh{9C_ zO#0ivR*)fob~?KNz9fUoX5u~EN52%<;QXXF3^1$9n`?iA00|Pl$?v$re0#5QrY2sS zTYP*VkOWiz^yTaXXTWulzsw}78iwb616r>;-#8`QZYD3+tX>O-f(LIIqs%QV!VpKt zcHc3Qe+S>D>ldTetQ+mYiJ>ZjVfC#r-16qH@_`9psjuJziN|boZlJOq$N7vYTH+0h zyabO`=;=SNmC<>*vdXBxzmb=|Ju=d5c8?p~kBkNPy3)l~V>l6Sd2gI^o~;h%BhAV$ zLYlXY=NqmXO&~dK%)}FKa2+>!U}yVL0EQ=5Vcd5g*Gu9g;>{G))VZ~vBK8J_xY1&z zK~P6Uk!rs{UU^kbI}C`qTt7a_Jdc}2|1>-r1*<_Lf9|xHW$F*e-Xah69Q}Rnk;b$) z*eb+r(6UI(DKePzNkT#N*rO84s9N0dz1cz{xzm=Qnov)@Ny&UFWB29Wf;DP;+@=mJ zCCJ&EtvkyK!VMz~f4A}Khr>wL6sbe}8>=M>B!LE(`X~E%WnNso^Y^xgRaZXb^=jzW z8h^RsfzHweC%rnFYO`kBym=$HH-hU__g)K(Tr@tL)oif0D5AM~m2S+HfX%U5^XNrN zAx*89CEdeaaxj?q(aFgv=vtO=8#weIRp9Xiuvzi`PFiXQ+jyv?afyU0uk2$JfVLUG z+s<@GfY|l^hp(4RBI?kx^#RZSFU7sbLgr?sJ82@m^huLC_fLeie8M;JuQ_4#ditqm zr31;>^m-=r3Qg_RjyO9$OzhK%u?kE8wVCnJTB-j^p4`(e7KTgJpX^2}W_j&HoBS}G z4H^C6{vF>(A0c`_&o=lAkpqwo*$Z z6z>z%R3W7Il^z)w9dE_Hv&p*cL9^h?f|wp z_0cWgdAIs!VuV8~aJ$O(XIW4g20a9LzwHF|Z$gGVE)$ob{5>qPt4AJ3w$JtBF&dHe z?F$b>J!jMO(5W&rZc)6)*XNeW{WoF|<^7oeig$X2jfby9I62|r!1^Ubr=ybIjiGo^Tn#CCDJtODeYA>&Gayp+*o@U__=w9TI(;~3BL#qgAB(Y5g>n5{+=htSWvj;D$5L(Elpme<)-agoyD=R&= zW{=|pKWc2RenS#DMP=iWdD)z<@G_p)-PrBo7IQHBgQUxUD#XFyQM*z~ZTIHq4fI9A z0)mI3hgyMz`tcx65UyP+G7;wlfh2!Xt62ZLUR!L+Y-+0PiBc6v zz@)4`#&XiRS(s#mYLQVKOTKP2nJ$;$rmVAF(qgJ=f4>wBox=_vYo1BJ4b`L3fynss8NR4s=oD^9t*Y(av>K+VFE}1_6Pr!!hb2W#DUgMx$d$ z{Qcp_n|Dnb&5-k)%P|`9(S8irUN>880en=9wNmFe5!3FDyHm<2{tL&RPPGT#F&HF_ zVQ@GAJk=M15iBq@Acbi=OR!&^-3RYr0i$PSh1{K)nZZPZ5zkpe1LZ=2RR69cLsh3I z+yd4#>7se|*YJ+#Amva*rb?c?kAS;JM3+T7oZ{zKz$Vuh=ja%6Y6H{t4i3F#a-v3+f(hf7W5mDKJK;We!roMukC=GgAi zlc|eWQC|D)bF1g?$cTurQt9IF-o2ZhQX23~q_n5ufe{hbO{4 zFe%UdW`#{Hw@rD5=;2CXyyfh_K#%GNn*P~el#ZhKJf5?;Ql9O@;6ccgXKKrKP7BeA z;%5RN+&d$cVeRH!$gxQKcY_mHmOqQ@h~ z4lZdMF+N=LsOd?XA)g|$+8v@LB6i6mpGc#e>oFdWx&`sp0#V zhm2!;H+{u|HU;6}ZzLL&Jd3Xp3C`Sh{ZostUDq;;Rh2c6N8e*&qQ}}X`~Ry#_E~Kz1$w2Zb^6yIe0%m8z%L*RXprbSYYj8upFA8SLJ_2| zuC6y0oA;e_&p>y_`;)}BJ9~PH+Gm@eRCG&`HZFxiBJK)|L+80Aw4+q*O-}KhdguAy z8MZLgM##>QFv>r_(Jc6xiWoa9#Dm0F8Hd1Dpv(7HGX5AQ-Q)H#>2l05tnZSv;v~1-P>p#=q=t$hcI&F0)m|8>E)8b%Z>Q z-AORN@xY8cnITOR-1B!ozXC!+!mec$~{R`~7TKl`j}IZcg@zfVnxB(mE2ol-v~cC65C!>F>2>$ z;=fU9jpBgpD*K2)p8Sr=({$*H%FmnaGSvH_^=<#dTDzWr1H7qGG;*fc+ znKrL6(ni8-JQRW5D;uwA^tBFFLJ0R;v^;j&>b!zVe|TI-fDM_s^Bx}`@>*WbUt38! z(+zZmii;W|qgEGC-i;BeVAX`sfF0b{KZIR48iA$2BKr5unpD|Tb02h6duG| z@;gvLzi4*%gOv6!T(jPu%dd6Yno{Wtz=`1xBu*u}x@xZP12tqL3lhKTE6JIG>MOmC zm1TYuE_8Dtf8|nI342K6bPH1b0GLbn4Y2yy0o)C*H^R5IBw6`*+1k6&4UHV-Bnsao zLq8xSq}?^GFt6?-)6~p8>|~;IxISSPi&|+`&g>lada$m91-Z+MAtZPAW!ETcGQ*>} zHRq@7SA%=YjBuQXgWn&JZ$AuAM6~KpVV}f^(6uQZ)8gz_WH1ni@2$QVdmN_%f8 zPj$%w0$IRRb$3g!d|i`1kQhP18ANH6ub}f{^FD~y9bq`_J0?zvMkdVJ)O%{*EaRY8 zfxr;I+E7)!568``%QN_7BRUi$f(?1{^FK<$U0waJzPAkgJS$9-z4YAw;POdqvBK;? zV>KX~81C16SUr)Z)z#HC@%OItJ>jmzrrxJz{p``<_cLL1xJ(K%1VX+@OW+nKg77c23yd1 z24yybZ|rn9VT0ZEt;3~idiGAM&?)xQZ}IuZjwk{N6;sWbzr z#-o`K@l$ZlTW&v;UyWwdYDxV37Pz83TY(py)TibHqNuyxUc`TB&XWAOYeX);=_Fm) zc{Z1S#Q%>5z->Z&9g!3KQWcYPODO$!277@O@2ly1Gharm>+U*>_5lY(Mx4e$&7VDB zha&LyQg!n@6uP(i4DLr8kRB{iNy=ufmMn4`(nJe<>2Cg>2JjJeM*D1rrkCGvsTlwMU%xeh|nhb;1j5 zitK}+0*!}*z=))intoi@I*9(TfO-*R(=Z9uNFh~N$3y^2P2S?1VT&lpDXn=b3HN+V zSrzfqVb5zxx4ibU2_JmOf?jbjlXo-Ahr)xoKf%4Bz_|RM_TKU@$}j95y$Jn(&KXGTLt0X#85)rWX@MEKW9Y84=llGgbIyzNCmdhOhs};F z*0rv+_f4!e!m+ySE#88Dd;LhOI3+&9eo+*dMHfqq{=s~MHC?p`beYs6NR`=}2agp^ z{ETcP6_PGJBgkuQ^h)|~l`}VleVbe8-m;@^(Qde$$yWEG@2KD4#dxWF|IWxo*Sm|0`=T;$rneSv=PnKel;BNvd#1{L6jJdvd`Ff-LgZ+7l8_k;p$jum zyc;$oC;SFkyIQdC4Mzg*AmwTP5_kwzQ_2d zZbhUcUD)3S5c%i41?|i!;IN;Q)gSgunDRjmc`mJ%^QPpIr}7tWWA>pA{M+kx9AHK{ z9X%SE712R^AJ(=w;5Q+N2J0l0QY-TE4^_z`#x;{PxeRJ)z4uqtXyKj<=O=p#rly+s z30wbC-;~%W>nGq}X|b#-V(=w$|As!kDF33&+HK@wEJpxoJe!oK^)+&J97Ko(Wq4wz z5Z*rI{<7s>)s0%v&ELl<52lxGplUiPLUnrYOG0wGIU6EEH?0CU7tYgsWA9)V%xwtD z1fj|J+56r2o3eRgATXNSROzjbI`R}FT*n`K1+WUHTq^}@3`P)6^I8l`4s8ZOpSnj~ z4)2mv*M}pSja~IeR$6AK^|zb~e`6Pk4;HDU5XZGSs*mA9(a{#`*MA*B)o&~?n8}bu ztO7ptcK2;0I&5>~K{`U6FNa+1I$XBNZn5B$TTg(hZpYjjJ1Zk#5lwlP%ZD|vXb|4Y z%Y*OQ6UTZP*P3N}eb}tD9_>!h%INfL-^b&In}_OsVVu!MHo(7bM5Nil@o)cN9f%p4 zwkW$N(F>+DqX_b5Q%_d(>q1!eHLfZoDLlA&pQ4SjmiEM+AeHXWPxl~kOu~CE+!|)G zX!BHkHm`#!H*9O`4;sf#K%e0jNAA|uwk^y*rfVxik3}=#?fq)!5V964;v!sMqWDb< zVqYV2saIB|88s#iBdD0iS|yqh>hIDfJy^2KP4ycF~E0%3(yBskp@E~D}{ zh&4IgHS$q)|Ngdcw9gJsq7`wq{X~DRK|rFQlloh52?&wJ$i? z#SayuqhY7&nB>ol;K|^xt14^Ic|^1Wa2|emt>+>KuyNTqt`CO`HZ$9jC%;5?&e`$t zx}#b(Bj3p{VhFYS)(4eAr=hRU|KBT;mp z^0%4>h{nf?W3cs52Afg%9q}1jIDxN#wq<$$ZMB{EfgQbQil6!?F$)O{@R~Td+!9Fj z)mk9cpGzib_Gf+Z|7Yp|=gBL#KI@x8k$|p2TrSMee9Ytf+B~ea-xgJla!A0qTro^ZYRU-#UGtz-pdjAN`9!M z6oDE?3I{T`9!qU3fmIc+_p2rf(^b_>f3GQ{{^}v>P7F3d8s?wNsV8bF0Tx@OQ(M%N z^|u2DMfXB7CQdbM;L+y$=q;1ThH7GPmxq zAd{B&t}xhdGR$?zh)ilFwpL7>QTi#Grb2useLXH<&GEkK*kMWYHxdY^&50EbT^5>` zW(-x|7Zlt}306rH51k*Nt4>TwX+bwhZVgo6Q3rfZ|6naFY5{jX z1ui<)>lFMES8}F>=&3J50`CVujf(L>fH^f^rMDg4<*DU|%cke4<+_RWE^=Ufmq&Kx z*JV92+Y!9L5ox_onx-N5dlH0DsoG>`0IK0NnumEEXk5rn1X%xZghC9aKSG@Zpohb0S_H+E?M<((=ymHXn+cI952Q z(SRTuaJ}0%&8-l;z#iD)q%}}t*sG#ng>fug@+Q9D_>UrL%ZYyhn|a?E#r1L5^`mi& z@z?jFc%zvfvXZGif-C<0<}U9hHhm2ARb0iCU9nw4-rzs>NvfsLLu+w72kU-2IDe3P$apY2Fjk>5ii%$w- z;neV`6Op`Kgb;Cnnzm+qNoN8SqS;bkEKQPXbvDEf$tVQQ4=T&Cv$HO{lRld*Mas?Q zsez;*Q&wNMZ~ZGT%@K}&_pyP{kYdv09Nx)=Zj8uvXr?g%!$SIi?77AMu{Ki|aHNUF zp2zi-Hs~*uIZ3W(n+FO@F;9jzy^8bm9cNLU+9UUrWTSs1C@!w&etY+Ho;tZ9CT&P_ zQgGkHS~_d-^jD`O5X!8x+{1ff}YG^I_Xs-BUhDnglz0!KAjqvt|N@ z=V%&D2nJ(BYtd6Yv@B=ZL%&({;4P%a|H)ET0&|oNV1s{aUUu7k4?g_t>x`rX~;Wc0R=WwE8#*8iI{PU6|F73t* z!AYoqOepL5Q~h?3K^vMPI!h@s!E6*cUpd5?lit}wbjLkEMzp}|1ZNxf=3|2CC{}pnF}H(kY%yEkK1PYdwbC)kZE6;S`$!vqQ%!&m8iZjPgRcm7_z-TpZ+ zibCCgicQfWPs(kVhR5~*?mG{hc&m1gs$?SUb~igFHa#W|{c2KZS$4CC+7xL?1fBo4 zTFpjpFEMehLrZY7U0Rba2{t07NkW%t)B^$vXqLkWUwp~D(a%b0Q{pJjS0o1i+$flqNG-i2VwiS+ zxQg{Fsc+J&vqA|_n!7M%+yvufBdOdD+mFgu4+y&M3%thALOcXzDcd;s$$|3$W<-pK z_V7Est54XDz!#m?9N=~ybpvI}V)Wsw#WR8}wD(UBHXS07cuht`jB<32GmdJ4_JnZ7 zZ^03(?WUF*`6O|1VOSiO2B5^ua%!HDfCvlh!VmfR#bAFUt!)Qgv%G?QyXtv_9E=>r zdEHUM&Zou-)EAP*>y7VkQ3bhuMl!D~8YvE#id9V2TiZMVHi9nz&<#$yQiA$q;0myZ zf#=E|YXNu?(vEPu@rvcMJ8|6=2!NregBSlqm3l$rsv2A1a@{9&rf)zfW%fzDy(7TaM>`h4cP3dv*-? zznz`72JiEo_8MLY_bZv-F#T2!W3cs85UCuOUXO-*R<`nGzI_P56QK&QJzSW+e(6#5 z{X1-C{n=vN*$Wus?=|HB=il6amaV`=CWW2aZMC(hRi`b35^3n*o=IC*yVt?ZPc;CoQpNb-PhY9EHUF0_$kX;;}*#rw6t z8FDo4m9bW{)UYMJ0Ud!rDhcUSnz*>Ty8a`2HvMKlQE^)5W8!kDmQOj?C&UKuUqvM) zo_Q$*B%WEB7|EPpz9Pdff>Ci-VqB<)IG}><8-*|_w3bCZD^bCAiM2jhWE5-3%$J`vh8-3;fqv>>fQsHT}2Sy z$>Kp&!H-X^N7^z1nxNG@Awi2nHBEqfg#JR9J0aR z&2Imz1qd0=VRncPNE~Cd1b5%4qh5U&J%QgaED@Jq%DR5BObxmIXV*hN&}EnwwTOah zkvoF?g_HcrA}wQKbXWD<h ztW2tT4Ed$Fx`&wl*wughE6?>2`c6=f{8nBOZDn`GWraEB4n%kp>nMNIaY|^JnTEtl z)}5$_t@qxAccJJSo*f>HcdB>MREylqX{Y9ld}=Idi<%-ahAb!V>I|p%M`a0Xf*F2& z+*o`*nV)80TXk!qpBvi7ax^%3-QAmI%*@I)GpY&TeSqlYu@IjLlM=3&(frlvG=n9TB+$VUYz5kBM!SN^_R$b?5k$(6m zvvu*L-c$sG*Te~sF5xRF!u);XFGa8{$ErJ<8#Tk}y5?q0KkZA$iWj39qv)cFG}rS> znGMC7z@l9;oI>?0#ts`y!abvujuToQaf?VNO`B$Vj7?%I<{1ek=VyduR$oci(o9R) zawb!|=68lY3*UC9>ujFStMZRBXVjwTt`7xMJx(;Jw9?Tp#oNYXVtk<`yO|&+apVE^*!H zPaxZ@y?3ThXraS_u9#YaKQdT#umOtaxfA?Z%GIi#waw61u=FNkY^+2y?FFGL0I5gbP8U-Wkv1qv&A7lbUG?pEQL5da1j1%u|zP3TkW==xA*hE*u5T7= z(g%1uUy;m)UHQbtKrOu+Nf!nnQK_x`i6NRet|T@&Ex~DA0-sC7#)cOeT2-S!yRv!+ z<7WFS+#v4k@(>dy!sohhY-g~x2nN+;dOG`RveH`lNbovHEc|paA3feSL%+r)7&l^U zZpS$AdVF+DREhl|0S*YF1W&V(v0T4(Zy}8HUewDa4{9;bDZOsIHICZoNC!v9vq+-w zW)MM?mTVwjBx}BSROaDjo!A$d&>5SjR9fB=);o%2iwSr*2W|uq9JF@=pynqz<`D_t zaA`@-a%*a8IN3#*3U6ErT1o332E{5f0&qwl z^;7+_!h2%UI<{lD6=x4SC^q+zf!9Lj?4`*~k$x&;4#gtZZ_-&VW2z0xXzC>55lV0m z5%N$@y~@}8aC`_QLQX!bDeEnv2BX?~!QxQkp_DoEC%70cJg>sy`v7$4A0S@;P?rwo z(sw1qIvoQkJxM%eEHMpN>;tAU1012TLY>bqL3uu7u=X!)G>{^Ofw9d2B)}&ohhM&5 zn`cPmEHV1cy9&J^#7>R;KeCYI+X?lS8dp}fY>@#n7C9d))4(s(sq53 zo+LVc1BO_qN>{yEtzK(N`s)k*yv@_l^*BT4UW;ei3Z1~R4YAYf2)TbU;VrEuj%70@ zH$T=p^e%f}=^yPLX|_?Q0nqe$^@9TIMGpuH4e!^>ysLIsf}J}orhC!vD1v%wqUYS_ zBfhIEB=_Utlb=iC;U~1y7i@&FQ>46D((6SxT(zgYJ3q0IQc(%x8@9RnhWz|#>Tukw z^hikZTbY=^L%kyLd3%o6PK*g#yok>)O;eJV5{I(NBzz8Wno__suw?!mV%l%-k%Nl- zPVeSno#Szw5mU8@%~Fgv^T_&`<9lo|FUa9waCMo|d-(5~FMD96wfts9ej`HR&Wk&P zq3Pgk9SzFvSIm&$KwDS~^k3>vj3!^Qi?><7AKspM=;a(eO|sH>>F)W6{KPt~1mJaI ze=-}80eHS53Ni}bllHy}ine$OQ^C+v62{Sl^$q8Y74*>I{tr|lQ;?JUYt3(IiyFceU= zfT@TYK2N9$ccn5brD09=H#cFHtPxP_ayYj=66J~*ruZcfroeMqzGDl5dGSW zHG%Z1tZoG7KA_e9?p0IlGp9Aq8}dE~17!||9-#CGd@~~$Gb_z?4p1^3Oc~Vw;)VYP zt+K%#BOg_k3^ok)=fx?l;(Zbj0%x)h(N4eB>w7h_v@6L{6^}UKFO>VkE#tc1>$Lz% zVFrT@S?ZuA*ndqrKx6y|TJNo`9)rIrlVcgiq{{ma0v{4!#MpkzB^ei!zs)HSfB>H6r#m$=Fp=cU`u>d1w+V~? z5upqcuY*HFJHd3*mEuK*`sj94`%vfql@b93;``sp{D4=SBiNE>Udv+WSmqe4RD=9B zX}sDwxKr+I=nmF0!U-YNU2O1EiCpPNH#J*SoVIZ;va@S!#yxv>v1HMpR;bxMIwrH< zK4%AQ=MH}t5zqbQO#i@=P}B8@4tf55E1>vIePs1ZXyyoP#4uxX^Kv>Ek7Pp_ltL-aiC8xUR$RYs7y=+GErWSAlf>9=2sUn z($2Sj5(m~WGYZmWeA7ZSqvdUBD=e2NJ7$!4{0F6=ztw0rPA~v7sU4XNz8!e44Glq` zq!ARg!iTwEGF-FG=Q$mSeBF09Kha()T%u5eg@z(TX0r8 zYuvY&1zGUBBfRkW-3_KqU zJ&O4D?HeEsXJx#bcZY{xx7s@T=avyz+jWs&gg-hyxZ%UxQ~59iwzyZDsBrYC!IPJ|lU*vzS35Y>5QN_X^wRX7MN6H_5#I17=cLu+p{Itwk|fj5hwq3y;cCDPha@ zY|cB{qiG9nH>i za9iFKBCz70y#60JOHxUy|C#z?D?2OO$l}E#(S}&AH@F2=c)qH6UZY+r*-?|vVoZJ>|vI2o>9BEg@{=8USsd4|DBJ4yz#;Qb&8J9ly;i5 zn4J_aFR4t`IwSj4r5@EiEh&n=y@(y{8kZLM`0cSMi0gzl8HTF8qia!`OgZ~EK?k#U zYMIM*^ul|r7Ihce<_3j_lIcV_kxf7=(4l<(w0k-{{>JO#(K2_Izyl^^$#i@FLLCZo zq68u*4?#q-Qf0*1*T6Z_3f7yeM@s!QoU3@cvb@ffT%xN7Rluj>9CrOdc_Q-3i_q8JOc?0)XkRsRxX>X$zzUo*!9R6j~kr z{TQm-=9>-<4or0ywPiHiRY?6}v-*qL%VJk4eT)87F=uQ_6|g*WV}&8ziaOrub%HiY z`8f@0tNwO-3Mh@R`@YtBJ-ki@Mga2ql9TYdikD;R7)|Sm!%*cY=o{p}icXax1isv) zQZ(^Qi>|KVJ{5K;p*iGja)S&p zqEDO;wv?V52oA~!r?^tn`4VAWC`rWe*U-DtERf)^gyB%3^x2~+_xkz9OT$nEMg4(0 zPK(aT_n_PwX3!asq1&6ku6XjbSFZG3ZlK8b#R}&lhR7zcS(@0*D%6cpNYE@83Gv8i zzi`;7`ZMMFUF?hmh7`jzOt}_GzAGCi@je;PufiVsWza#)2tl6qNp43*>WmH1gP?OS zRaW+gpqs;vHLaTbH;?H6xq!xXW#(?ggrPm&V-B3ZhNiCkb*}dlNW_)*)ZcIiO&i}y z@@G!VFCtJmIODVd)q1#pDuTIdUHT4A{qi9@aL)!u$)@|yo5?px)&slGj(oz(IFu{GE-JJ@Ie{d^t<#WmO+Lv{zVscuMav0!qw#d31ecR z^bSiJj*j8a)j=f2JlLVaM@o>9O4W%T?lLm%7iX$d2WdXG2RYwiuSYzjKQ+Hoi)CeD zF#&BK2*o~-o~!5e)|*wmbrh%+k1z<#$71V5{Rk1fCM%HLpj!-6(?9YnK?_|bsy2lF z`Md2Q_}Q`scUC)P#9CXHq+Q0x`L9Uq`C(%7&Yg-U*5+MqQ}72P+xpp~opVO&Q6H~^ zQbWQHk_?m%GFOiy1|^_>ZnlBvn$6`*p^#!1XxfZ-i+OWDW13s})y4~2XkcE%AkbKZ zt3FbbJLX^-toAt9bkXImwHxdL*6;{yI(XE6qQcrO1VI8!Yg4!Hpq6*(35R2@kIh8k z2?qMd0BBGbpiftVx(Z4 z&#X_+bF%**ov5qbBXR&k*KlOQ5rkJ#AoFtDK@W}tkIzsR{YM_(#OAEQN|`@s98En` z#;z0qD(JkiFC}d(GlOY*5d$7~zgQBlI`iN*sI_8^qLcVSrWep~+J)`MKt|;DZ=5P7 zyKqdn_r+%wP8&7$r(KM{3qqgc*YGK!%S1A%@F%Z3Li#m_R?C*@Yf`3+8!Gc zHRMkQl0ryq+E(GAep27a<=T-P`)X5j>r;@^&2}8chD*rj<( zB0Gh;OBoJWcIZyqgoz3D8}oBootGp)`x5Mj4z{~S*92}p;>`G->g zA_MrodXo){Llv3@2iRs9&<%`ue>Os{+CN=B4egXUJSIBY<4jDUz|#KEoxTaTHg>g) zE~q8Lo~5i$+Fk&P#|l!9HQIux41NPNcf2!gbXsPVw!ftB@n^9IKhvXn+^X^@;MSUR z2tfP3pFsoSlU`gPq8dn88O0>-|L@ND zRZd+$*lGlsYg51mWv;X&Vw!3`RXzZkH6WTZ{rIZ!TgyTTwp^`u=iv$~d~7BRB6Kko z8OQgX+&4bi6#|V0N;m;tdmv>l=IqEwd;9QA?c}7dQvZei-26LL<&@_W8(JX{gh0q` zA}{f!<8-AT)gd?1O!^*T@O{&jDcaQhl9wQ2R605$f$Sc) z&@bL@V>tf?q;`6OE38KjtPnoYwdkz_4&)YO%sSo!VA+ImV1&{axf z$TDM;lmvlP#T5f&T#b)1qfQ+K?CjFU`%@sYVUQ!5I1e^Q+_=d%K}+(z=>80z1`w#t zOnsCny2Tx@{ozHkcvu^V(R*=|wftFBGBB^N4~HfTu^a zY6IYyn*n}-P_c76I|YG+lQ!3cs=CGa#T(@4L5+i=8|#{)st}0M>K=Z%6%iYE9Bx$E z9YUFcI@41p7&lCMBR4XP?qZRBddEv*CENa7Kb z1(tDDAe+yOF8mOioru<@T-i4B$*e0VT0QJvzMT*^GG3AXLCokdA+*9p*0E>-ycy7x zi!}mk%gf)CeH|TAt};S|ZS8H|hjYQ4XzUp}sw)gqmlu|BdaV*9oU~iAIIkPjg%~v2 zEzl*ncg!A0mbw2Vk7$Fzz1Hb5xc_5|;38)}DJNrwBZ_XufJAl$ml2=d2-?=bkh;rS zzTZmYRP|~MEw2l5;$F79CeT$azH$EA98{ zAbOZT89@N)Y8=pyL05{YQ{Tj@u>fmJv`4p!NB#rpJ0k(Jzyx>+%H*yEpvF zRNOWPc`zjZukonw-4pgl;?(5=%mKKBm<1uvWs8Z{Dk3yOj_Q2Y4s7YW4{kaipU5;t;Gfm}NB;b8_%KM|F?F@EvKmmrkW_mxGOopb$McxoBJ=&EbkjB*{cSP^pS8qm zMOxVg?>Ph^asDT?Bl$m`BY0u{wu5*>&1Q)LZfPR8O-iU~uE2punmP(*hdwZY;@D-( z2}5n}*UO>WglDX`NbgPurit^9P0hHCiO;EkO!MD%@!7oMW@TdXd;%^S)%^PxUw(J! zPcDGr@t>4bwaV?OlHA4bU(qdQ!C9GNkgGX29Ma&NuEjKPnFsa^+GfQ?YsK00^Z)l~ zM2!294}%z(^`%J#+ujAM%-BFYpZ)G06j(S~c(d4=c)zG^zba0=;+8f|r7ut}3SAzs zjY^FcLsw(-(L{gZs- zjSJq@xl)GCn6X6M_2kEzhC&yiXHm0MKwFh^KB-Hvs2>8TuSmY{H?SdvIE$1R+I|Vt z@~=f1#p8amx;KGt4fDO>f)r3Ql7%dc3~5>$?scBh%=={56?|rY)nDNhKH@l&8Ln@n zMB-m?X;sc?E2^r_4>lryX+Q>jTngSK(pJ|P_E ze`4Q}Ro{N#4;Q3ZI10KgiX7fv7Tl`%t7$-sNPN?W&9>ABMifL1?|Z z;$=?veygC_Id^dkn&X>ZK|lH}4_Y_pdc(}MZAMxvoSD>^CpzjH)|EhGYp3Y`Zs$1J zELHwbCzWqpbk=DRQ^$- zZP6Xw9*-V9y3VQvBq?1trIRM>GR@|z_nZz;1u&C8k2`~URFZN+OUmU;Q?+W|3s#d9 zhHampw+VnBe%W)1KyZ#ip0_~ka#h}w30Gyz&;Ykta(}ryc|T1O!F@nhBe6oA8CrDq zMHFt#PNgp}Z+w~Nz}=X^X(RMSq}6WPoy1MebN7d)%^r zoPPb@zR{(8Lb3ULTD)XUoYB0^+e~f#0Hwy`+wkj>KU=AspzV8%_^X4weu$q6)jk8= zu_`V6t`J<(yJk4w>vZiX+T#PxTfr;GYc&T4oKaOZng_(EZG-x}li9B@ivuXSWSEI4 z9M_i}WE!aCo`kzAJ^8hZk!Z;A*ZZ@|_aIs0b}=6~4T`Z=^PZ>fx&QJuzi=3v<3I4T z-w|}%Osp_=IFJWRFNqlMPhx&YYR?J+P7UdEXvR53q*90`BcHfNWX4E=g<9fYrYr&W zzzJYI7qx6^*21%4>3VzB94n1mrwSeyvzXoe)pVh%=+ywKvAXL+?Ca;|EkeBVeDAp6 zc)oYzFOBh_sfYgQzkmA^!xk27J~a}n6}|t`6v+(1yG9REGPAzEQ!AW&pSw|>JrTs( z=wO?0x0lYbL|<_P-2%-us>VhDMr8*-#ZUxNRlD4JCTtJGybEb{&{P^gq`V?L9>bQbtR6Gm-3f) z{8+tuI5MQC{+Imyu@&Mm5A?djGK$O1DIi1H{g}^f$(A89mZlp$ueuOgI4(u#IS%HF zbtB4%FE>CF7wRh1tr!dkKKiLow;p}FrECSR@V%};`5;YTlf(65HXDN`p0ECF1Cp3I zvF`Ih@r_+x1H~j5496$9A#Ra*nIU_uRgi*qHvftkY#4(Pu#7g}OB{*OS=Lx_mwDOp zr9i^0wD^sO&zNB}S19)n=%z0oIq=hy-4DN>P48k@n`_>QI+Jh< zATOO%Z+}SH$}D2=Fa-D3A}rAzCdIeiHtXK#q4;&~>v{hWJ)7sMO&vhksdzf71*+U! zhW<1+6GEO+gfB?7ikiZX5|nPiQ~Zy2sj3Dn zd|PZ``9yY&A-KYm^!L?SAEkuP(Q8*%LFxmXZ3?$tB%$?qaAV|SiBHIf9V@T%R&3r9 zqh*f9B#a9VQ8sEhePYwsxk;^l)spz=>!qIQDeqQKs$Ev(`+qv`(|+kN9Q{)IOD3VF z9RUv^2*=w$EclW_M7)-)Zp>zNyow zsdV)lzNpdSQj>aE#b)q6jUvHynBvWE`7rI2ES9c%nXC^S?kc9ysqT5;rEX&iA;;Tl zS+AWFe2Rn?Kj_t5DdQTJ?rH%2M;N)(3^g43j12^7_k^E6^gQX}(?ZB$brP8dBK3bw zm&%FSYhFTrp&-oLAC=_PS)uNl)Fs^tJjVSe;FN81q+7W>^{<}}*Z7fOI*zaEt@{#6 z;O?FXP;fu`LM%(yY)3M4UyAUT=(foX^4T5od3J#lhGRcIlk9`>@5krYdG3%{Kr06R(pBhSg^@P-qEB ztiP_aQR_KLqiZ{>=Wu4;k0x@P237AWBG}@P*P7PfDfmb_Pt2F$`(mjQ9#|&@Q7$O| z%8z3WMHw$&GUBV`LpP1@*S&xEBdiTTLBpKK;q|{{2n!$HYQh1z zMI2xT!EI#l!>(Oal17JVyYPLoztI7y^0NQ{ihu}Y9DhB0O!-#Dq?SD#pE>x=Dx-fB zng~)VB$bF_ztP730Em34eUXeU8D=`VDm@^A{LioD{rV8){Q!tX!XC_H4tIm^+<@YL zyeHY9im=D_xG~9s99<)ZVP^d}$8WFjAs+pK-vsb#H0BiC8DL_88QAaiM5GFq;?A&! zd)ka?9$duepU9&)p(=Trrys88WggbI(SiGzbW`ONmY;cY>s3-4c8;&vl!@+NA#QGw&s<@7i06E<(hR{T_fX{4pqqF)8b(8A&noDQS z+#8RmS7DA-&^e8PyzBM{y(qQgn>gFN+HG{uzi2kS%}msNfe8mVem>coO}Cwmh^jA5 z-)WoDK9=2o*gecFLB*zQ=rpVpEdOx7k6o zz3k_=n`8`PI~0Cvue43Te?~rFzO9Y@0k+)x>9&(Snnc7}2!9BBQ{~-&xhMffG&AZ? zhWQqqrU7#$-{8H4Ld`WVss2#CDK`&#s}fj>?ce_TfKD)it^6yJnJnf>LVOqKWyAlB zIxLZ?M}vz_#_viOWycM5{by;L!a>Ci@dFvCxm<^O%bR@>O_3Uz8-RjG-Bl~9(HmYB z_kU99h2k_87XBjLc=y@6{+oppBs0^%pP&M*vm;R$3~(m6@&g&t$r`y~Ekx9kkb0Vz z*ogY#xEWCN7sMOW23wb%ZkTwM5|csy{hD}*Qx6v{m7AX()kURHN?-1Vi^u;EK9&L3 z5;9B{e% zUtQY#wJMWvI~wO)Fha4LF&_l*Y-Q10A;Q}8o0@^cK0e6ht-u~IP ztV+Mp3%G@;@0{l2u+-B_Vy0gXRg!=0g9z?bR5_p7;Z-i+6VhTmV1q-mFt45JF@GAk zZDvk|;f5yy2B1!M6KP+7;M&0_e`|Jq`%$iX{wZ6<83#B+oa@*#q?CG9HO5Gl;2AhOc&_Inl zE6k)Nk1}{sbeA0#74%8T&zORdc#x+eU4sXb&9Fw8o!YATI-E)G_nSM}VHZSNeK@$Z zTy3DzlYeryU3_0)cg-GtoCLP^F4$UHEN%1W@05FGosvjh;0>GTWgDEvIA*3G=h9G- zUnFoH9DH&87vS$wkdr?RLN=3Ti)$_q9DpM=rmdL%N;y}ml^=Dl7DV&&_;*6Z(LY9R zwhBpZV|x(Z+3Ve#D&(4uSES%=hlDpy$4Jvq+_JQkv>m1D0THXM13wVvlxxBvAh85@=&M-zs$#0f^_=aE~N<$>0#AaBn z4mam^=)-^1k8Lf0OLAM_wkYJ?Hftx?+Cn=`SxkKqHMMjSTkTF_{EmrB1xQ@=o&~XYEonFbq4AAVjY?>uB;7eB>vjXj#8JcI9 z?dv;|^Q>~t8}l|e)WTGplVkiYV$?UU5x&Fb)~z~z2XmEycqVY|-&-;~C}`qC)ug@N zW6%qWm^io?{>E-*p=RP~%hX~xX8N{t^LzZDs(;A2_jj^v`+&QWWLTcXoBbJ+0|opu z!$0)uqNXK4Vog_h?@2kS+qxvAN6ApT^cy#*^a}W04?4f8No-)3Jlz@@4$Z_hOdWW+ zCb^`PLnXJD4+X`pvP?lGEQWEPXX9go9; zPaS*nwNx_2K=#BBuSx-pw6xeiDR|JI{}yj~e9S09#W;$6hJo|mp6N(FRjD8?gyL7* z9IyL!Wx0iUmsQs#=qq97A|CtJKs&ZyTT@;d+50E^fqZ83w?D@3Eem6$t;=cnL;01< z4QI?ke$+p>lk_N0eqFZu)&1vx&80HmFlzHLReC??9OR6-aW517{HLTD+{HAEhEE~X z`Wo&Q*V&mt2SJ9nqa4(`4glP)qV zToJAFbFkLaZE*QndGK%PG@w!>fx%P=3^Q6xTQ}E$xWg^n-u9Y3u2F0kQ?kV=Ou*xq z9i8Fc9)6^0d$AO`V(^S&al$sZ?{~0MhQ7xG_tUY_O8PVHgD`>=1_VP9!sf5e#Q;H8p#qp-=gC7R|*Qf3Ap@>1r+R zf}9EB(>bY(YOw#Mb>ic*;pD+fCB z*+sYvtYYN}jqa6SL#wLTPQi;S2?DOH^Y*mZr0JT?B62sy=YO=?o@g5p4~Af-ynet} zN4u1d#FJx5btXT>WvAl}O_jcHS7@~qs4I>V*;8a!AYbi4OPHxVFtpM7>!Zx!0P8ZN zVaYx2|K%3DwY;CP?3g7Nkx9wUBnt~uQBYgUay|b&ohs_=(hT(}_X+7vpLR$tcZx9} zI){>&tCnd}RwG}n3Ezu3MQ00GPZ-qLcc%q~;q}no03VBtAhjytZ}b@pB|oW*7p)g& zau4cz-ugUKe==$5@aosESw|x!t;Y7ijV2up@JWl~s$|Dg+W2uhCXWSBAtpWggO7P?cA!B@(W7<#bN;_tO& zxR|8yUTteKNw~;pdFq3#V(XZgy4x9R8oMwxj|dy~cfpc=e-Fstyby7pRK3{9G3P&h ze_2ox8s)GTYr(?AjpH2DN&6Bo{@W%Ab1kKCDWf#I+%DgZDi=v{bN5ryZ9yE zjqd=b*u7Z9n=B|AxOkZ|;3ei}G51S7TRhnjNx!MdH=&^gvvhEV4PPA`pF|(?mJC}- zJNGrOg$+cYeRjc0F8; zPZTv!4c!@QUkDtjdD_5pZ+;~HPB==C{Hgu33}IGvuNN>c@896I+UqS5-Nd1)#@9N# zaVrU9L7kU~gMJq#878KdA8X)SBme)u|BoG5#-xRDSi88t2^q)!R9;#IRxD-g_kRJ+ CVLHSB diff --git a/www/intern/js/sidebar.js b/www/intern/js/sidebar.js index 121d29f..76f9bc9 100644 --- a/www/intern/js/sidebar.js +++ b/www/intern/js/sidebar.js @@ -54,8 +54,9 @@ function changeFreigabe(freigabe) { const params = new URLSearchParams(); params.append('freigabe', freigabe); params.append('type', siteType); + params.append('csrf_token', window.CSRF_TOKEN); - fetch('/intern/scripts/kampfrichter/ajax/ajax-update_selected_kampfrichter.php', { + fetch('/intern/scripts/ajax-update_selected_freigabe.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params diff --git a/www/intern/kampfrichter.php b/www/intern/kampfrichter.php index d85d2ee..3360d78 100644 --- a/www/intern/kampfrichter.php +++ b/www/intern/kampfrichter.php @@ -53,11 +53,13 @@ $baseDir = $_SERVER['DOCUMENT_ROOT']; $reldirbase = "/../"; - if (session_status() !== PHP_SESSION_ACTIVE) { - session_start(); - } + require_once $baseDir . '/../scripts/session_functions.php'; - $access_granted_kampfrichter = $_SESSION['access_granted_kampfrichter'] ?? false; + ini_wkvs_session(true); + + $csrf_token = $_SESSION['csrf_token'] ?? ''; + + $access_granted_kampfrichter = check_user_permission('kampfrichter', true) ?? false; if (!$access_granted_kampfrichter) : @@ -72,7 +74,6 @@ $baseDir = $_SERVER['DOCUMENT_ROOT']; require $baseDir . '/../scripts/db/db-functions.php'; require $baseDir . '/../scripts/db/db-tables.php'; - require $baseDir . '/../scripts/csrf_functions.php'; require $baseDir . '/../scripts/websocket/ws-create-token.php'; @@ -106,7 +107,9 @@ $baseDir = $_SERVER['DOCUMENT_ROOT']; $sortprio = ['ep', 'p1', 'p1 kader', 'p2', 'p2 kader']; - $programmes = db_select($mysqli, $tableProgramme, 'programm', 'aktiv = ?', ['1']); + $programmes = db_select($mysqli, $tableProgramme, 'programm, `id`', 'aktiv = ?', ['1']); + + $indexedProgrammes = array_column($programmes, 'id', 'programm'); $focus_view_admin = $_SESSION['abtViewAdmin'] ?? false; $aktabtdb = db_get_var($mysqli, "SELECT value FROM $tableVar WHERE name = ?", ['wk_panel_current_abt']); @@ -117,6 +120,8 @@ $baseDir = $_SERVER['DOCUMENT_ROOT']; $notenConfig = $res->fetch_all(MYSQLI_ASSOC); + $indexedNotenNames = array_column($notenConfig, 'name', 'id'); + // var_dump($notenConfig); //$dbprogramme = db_select($mysqli, $tableTurnerinnen, '*', 'abteilung = ? AND (bezahlt = ? OR bezahlt = ?)', [$aktabt, '2', '5'], 'id ASC'); @@ -223,26 +228,20 @@ $baseDir = $_SERVER['DOCUMENT_ROOT'];

Aktuelle Abt.

+

+

/

- - - - - - */ - - } else { + Aktuelle Gruppe

'; ?>
+

+
@@ -309,7 +310,7 @@ $baseDir = $_SERVER['DOCUMENT_ROOT']; } } - $kampfrichter = db_select($mysqli, $tableInternUsers, 'id, username, freigabe', '', [], 'username ASC' ); + $kampfrichter = db_select($mysqli, $tableInternUsers, 'id, name_person, freigabe', '', [], 'name_person ASC' ); $filteredKampfrichter = []; @@ -340,11 +341,11 @@ $baseDir = $_SERVER['DOCUMENT_ROOT']; data-user="' . $selecteduser . '">'; echo ''; foreach ($filteredKampfrichter as $person) { - $selected = $selectedKampfrichter[$i] === $person['username'] + $selected = $selectedKampfrichter[$i] === $person['name_person'] ? 'selected' : ''; - echo ''; + echo ''; } echo ''; @@ -356,13 +357,16 @@ $baseDir = $_SERVER['DOCUMENT_ROOT']; if ($selecteduser === 'admin'){ $valuetogglemodeadmin = ($focus_view_admin == true) ? 'nach Programmen sortieren (Admin)' : 'nach Abteilungen sortieren (Admin)'; $styletoggleadmin = ($focus_view_admin == true) ? 'background-color: #003;' : 'background-color: #030;'; + + ?> - echo '
'; - echo ''; - //wp_nonce_field('toggle_advanced_mode_admin_action', 'toggle_advanced_mode_admin_nonce'); - echo ''; - echo ''; - echo '
'; +
+ + + +
+ + Aktuelle Abteilung '.$aktabt.' von '.$maxvalue.' ('.htmlspecialchars(strtoupper($allprogrammeabtstrcleared)).')

CoP 2025-2028STV 2025-2028'; @@ -630,12 +634,13 @@ $baseDir = $_SERVER['DOCUMENT_ROOT']; $arrayNameMap = array_change_key_case(array_column($disciplines, 'id', 'name'), CASE_LOWER); $itemsToLoop[] = ['name' => $selecteduser, 'id' => $arrayNameMap[$selecteduser] ?? null]; } - // var_dump($itemsToLoop); + + $indexedDisciplines = array_column($disciplines, 'name', 'id'); ?>