From c4be035890e2b4754768640d9fcc257b22a099e2 Mon Sep 17 00:00:00 2001 From: F4ilji Date: Thu, 22 Jan 2026 13:38:34 +0500 Subject: [PATCH] change nginx.conf --- public/vikon_core/assets/css/update.css | 1 + public/vikon_core/assets/css/vendor.css | 5 + public/vikon_core/assets/fonts/comic.ttf | Bin 0 -> 127596 bytes .../assets/img/background_login.png | Bin 0 -> 43450 bytes public/vikon_core/assets/img/throbber.gif | Bin 0 -> 8874 bytes public/vikon_core/assets/img/vikon_logo.png | Bin 0 -> 43898 bytes public/vikon_core/assets/js/update.js | 2 + public/vikon_core/assets/js/vendor.js | 2 + .../vikon_core/internal/bitrix_inclusion.php | 8 + public/vikon_core/internal/config.php | 86 + public/vikon_core/internal/filesystem.php | 353 ++ public/vikon_core/internal/helper.php | 238 + public/vikon_core/internal/path.php | 218 + public/vikon_core/scripts/captcha.php | 32 + public/vikon_core/scripts/check_token.php | 26 + public/vikon_core/scripts/feedback_abitur.php | 77 + public/vikon_core/scripts/get_config.php | 15 + public/vikon_core/scripts/get_token.php | 39 + public/vikon_core/scripts/refresh_token.php | 32 + public/vikon_core/scripts/vsoko_feedback.php | 74 + public/vikon_core/update/check_curl.php | 52 + .../vikon_core/update/check_entry_point.php | 26 + public/vikon_core/update/check_filesystem.php | 74 + public/vikon_core/update/cleaner.php | 59 + public/vikon_core/update/complete.php | 44 + public/vikon_core/update/cur_version.php | 1 + .../update/download_module_core.php | 239 + public/vikon_core/update/get_access_token.php | 56 + .../vikon_core/update/get_module_version.php | 33 + public/vikon_core/update/index.php | 226 + public/vikon_core/update/is_writable.php | 31 + public/vikon_core/update/make_executor.php | 50 + public/vikon_core/update/purge.php | 69 + .../update/refresh_access_token.php | 50 + .../update/request_generate_part.php | 44 + public/vikon_core/update/request_new_file.php | 120 + .../vikon_core/update/request_sync_file.php | 131 + .../update/result_check_generate_part.php | 57 + .../update/result_download_part.php | 229 + public/vikon_core/update/src_executor.php | 132 + public/vikon_core/update/start_sync_files.php | 74 + .../update/status_generate_part.php | 50 + public/vikon_core/update/sync_root_dir.php | 109 + public/vikon_core/update/sync_sub_dir.php | 100 + .../update/update_module_version.php | 80 + public/vikon_core/update/vsoko_feedback.php | 77 + public/vikon_core/update/zip_helper.php | 5451 +++++++++++++++++ 47 files changed, 8872 insertions(+) create mode 100644 public/vikon_core/assets/css/update.css create mode 100644 public/vikon_core/assets/css/vendor.css create mode 100644 public/vikon_core/assets/fonts/comic.ttf create mode 100644 public/vikon_core/assets/img/background_login.png create mode 100644 public/vikon_core/assets/img/throbber.gif create mode 100644 public/vikon_core/assets/img/vikon_logo.png create mode 100644 public/vikon_core/assets/js/update.js create mode 100644 public/vikon_core/assets/js/vendor.js create mode 100644 public/vikon_core/internal/bitrix_inclusion.php create mode 100644 public/vikon_core/internal/config.php create mode 100644 public/vikon_core/internal/filesystem.php create mode 100644 public/vikon_core/internal/helper.php create mode 100644 public/vikon_core/internal/path.php create mode 100644 public/vikon_core/scripts/captcha.php create mode 100644 public/vikon_core/scripts/check_token.php create mode 100644 public/vikon_core/scripts/feedback_abitur.php create mode 100644 public/vikon_core/scripts/get_config.php create mode 100644 public/vikon_core/scripts/get_token.php create mode 100644 public/vikon_core/scripts/refresh_token.php create mode 100644 public/vikon_core/scripts/vsoko_feedback.php create mode 100644 public/vikon_core/update/check_curl.php create mode 100644 public/vikon_core/update/check_entry_point.php create mode 100644 public/vikon_core/update/check_filesystem.php create mode 100644 public/vikon_core/update/cleaner.php create mode 100755 public/vikon_core/update/complete.php create mode 100644 public/vikon_core/update/cur_version.php create mode 100644 public/vikon_core/update/download_module_core.php create mode 100644 public/vikon_core/update/get_access_token.php create mode 100644 public/vikon_core/update/get_module_version.php create mode 100755 public/vikon_core/update/index.php create mode 100644 public/vikon_core/update/is_writable.php create mode 100644 public/vikon_core/update/make_executor.php create mode 100644 public/vikon_core/update/purge.php create mode 100644 public/vikon_core/update/refresh_access_token.php create mode 100644 public/vikon_core/update/request_generate_part.php create mode 100644 public/vikon_core/update/request_new_file.php create mode 100644 public/vikon_core/update/request_sync_file.php create mode 100644 public/vikon_core/update/result_check_generate_part.php create mode 100644 public/vikon_core/update/result_download_part.php create mode 100644 public/vikon_core/update/src_executor.php create mode 100644 public/vikon_core/update/start_sync_files.php create mode 100644 public/vikon_core/update/status_generate_part.php create mode 100644 public/vikon_core/update/sync_root_dir.php create mode 100644 public/vikon_core/update/sync_sub_dir.php create mode 100644 public/vikon_core/update/update_module_version.php create mode 100644 public/vikon_core/update/vsoko_feedback.php create mode 100755 public/vikon_core/update/zip_helper.php diff --git a/public/vikon_core/assets/css/update.css b/public/vikon_core/assets/css/update.css new file mode 100644 index 0000000..7d97339 --- /dev/null +++ b/public/vikon_core/assets/css/update.css @@ -0,0 +1 @@ +body{background:url(../img/background_login.png) no-repeat 50% fixed;background-size:cover;color:#1b1b1b;font-family:Inter,Segoe UI,sans-serif;margin:0;min-height:100vh}.wrapper{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:hsla(0,0%,100%,.9);border-radius:14px;box-shadow:0 10px 35px rgba(0,0,0,.25);margin:2rem auto;max-width:1100px;padding:2.5rem 3rem;transition:all .3s ease}.wrapper:hover{box-shadow:0 12px 40px rgba(0,0,0,.35)}.header-content{align-items:center;display:flex;padding:10px 0;position:relative}.header-logo{height:auto;width:150px}.header-title{color:#1a1f71;font-size:30px;font-weight:700;text-align:center;width:100%}.vikon-logo{background-image:url(../img/vikon_logo.png);background-position:50%;background-repeat:no-repeat;background-size:contain;display:inline-block;height:50px;text-indent:-9999px;width:150px}@media (max-width:992px){.header-logo{display:none}.header-title{font-size:24px;text-align:center}}.btn-success{border-radius:8px;font-weight:500;letter-spacing:.3px;padding:.65rem 1.2rem;transition:all .2s ease}.btn-success:hover{background-color:#248f55;transform:translateY(-1px)}#modules-container{margin-top:1.5rem}#modules-container>ul{list-style:none;margin-bottom:1.5rem;padding-left:0}#modules-container>ul>li:first-child b{border-left:6px solid coral;color:#1a1f71;display:block;font-size:1.2rem;margin-bottom:.6rem;padding-left:12px}.checkbox{align-items:center;background:hsla(0,0%,100%,.65);border-radius:6px;box-shadow:0 1px 2px rgba(0,0,0,.05);display:flex;gap:10px;margin:4px 0;padding:6px 10px;transition:all .2s ease}.checkbox:hover{background:rgba(230,245,233,.9);transform:translateY(-1px)}.checkbox input[type=checkbox]{accent-color:#2e8048;cursor:pointer;transform:scale(1.1)}.checkbox label{color:#333;cursor:pointer;flex-grow:1;font-size:14px;line-height:1.3}.checkbox label .text-danger{font-size:.85em;margin-right:4px}.badge{border-radius:8px;font-size:.95rem;padding:.45em .75em}.footer{color:#555;font-size:13px;padding:1.5rem 0;text-align:center}#progressbar-container{margin-bottom:.75rem;margin-top:1rem}#progressbar-container .progress{border-radius:6px;height:1.3rem;overflow:hidden}#progressbar-container .progress-bar{font-size:.85rem;font-weight:500;transition:width .3s ease-in-out}.process-container{background:hsla(0,0%,100%,.85);border-radius:6px;font-size:.9rem;line-height:1.4;margin-top:.75rem;max-height:400px;overflow-y:auto;padding:.75rem 1rem}.process-container p{margin:.3rem 0}@keyframes rotate{to{transform:rotate(1turn)}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}.static-throbber{animation:rotate 2s linear infinite}.static-throbber .path{stroke-dasharray:1,150;stroke-dashoffset:0;stroke-linecap:round;animation:dash 1.5s ease-in-out infinite} \ No newline at end of file diff --git a/public/vikon_core/assets/css/vendor.css b/public/vikon_core/assets/css/vendor.css new file mode 100644 index 0000000..d301e42 --- /dev/null +++ b/public/vikon_core/assets/css/vendor.css @@ -0,0 +1,5 @@ +@charset "UTF-8";/*! + * Bootstrap v5.3.2 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg,hsla(0,0%,100%,.15),hsla(0,0%,100%,0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33,37,41,.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33,37,41,.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0,0,0,.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0,0,0,.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0,0,0,.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0,0,0,.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0,0,0,.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13,110,253,.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222,226,230,.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222,226,230,.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:hsla(0,0%,100%,.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f;color-scheme:dark}*,:after,:before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent;background-color:var(--bs-body-bg);color:var(--bs-body-color);font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);margin:0;text-align:var(--bs-body-text-align)}hr{border:0;border-top:var(--bs-border-width) solid;color:inherit;margin:1rem 0;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{color:var(--bs-heading-color);font-weight:500;line-height:1.2;margin-bottom:.5rem;margin-top:0}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-bottom:1rem;margin-top:0}abbr[title]{cursor:help;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit;margin-bottom:1rem}ol,ul{padding-left:2rem}dl,ol,ul{margin-bottom:1rem;margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{background-color:var(--bs-highlight-bg);color:var(--bs-highlight-color);padding:.1875em}sub,sup{font-size:.75em;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;font-size:.875em;margin-bottom:1rem;margin-top:0;overflow:auto}pre code{color:inherit;font-size:inherit;word-break:normal}code{word-wrap:break-word;color:var(--bs-code-color);font-size:.875em}a>code{color:inherit}kbd{background-color:var(--bs-body-color);border-radius:.25rem;color:var(--bs-body-bg);font-size:.875em;padding:.1875rem .375rem}kbd kbd{font-size:1em;padding:0}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{border-collapse:collapse;caption-side:bottom}caption{color:var(--bs-secondary-color);padding-bottom:.5rem;padding-top:.5rem;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border:0 solid;border-color:inherit}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;margin:0}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{border-style:none;padding:0}textarea{resize:vertical}fieldset{border:0;margin:0;min-width:0;padding:0}legend{float:left;font-size:calc(1.275rem + .3vw);line-height:inherit;margin-bottom:.5rem;padding:0;width:100%}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{-webkit-appearance:button;font:inherit}output{display:inline-block}iframe{border:0}summary{cursor:pointer;display:list-item}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-inline,.list-unstyled{list-style:none;padding-left:0}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{font-size:1.25rem;margin-bottom:1rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{color:#6c757d;font-size:.875em;margin-bottom:1rem;margin-top:-1rem}.blockquote-footer:before{content:"— "}.img-fluid,.img-thumbnail{height:auto;max-width:100%}.img-thumbnail{background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);padding:.25rem}.figure{display:inline-block}.figure-img{line-height:1;margin-bottom:.5rem}.figure-caption{color:var(--bs-secondary-color);font-size:.875em}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;margin-left:auto;margin-right:auto;padding-left:calc(var(--bs-gutter-x)*.5);padding-right:calc(var(--bs-gutter-x)*.5);width:100%}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-left:calc(var(--bs-gutter-x)*-.5);margin-right:calc(var(--bs-gutter-x)*-.5);margin-top:calc(var(--bs-gutter-y)*-1)}.row>*{flex-shrink:0;margin-top:var(--bs-gutter-y);max-width:100%;padding-left:calc(var(--bs-gutter-x)*.5);padding-right:calc(var(--bs-gutter-x)*.5);width:100%}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb),0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb),0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb),0.075);border-color:var(--bs-table-border-color);margin-bottom:1rem;vertical-align:top;width:100%}.table>:not(caption)>*>*{background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)));color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));padding:.5rem}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width)*2) solid}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped-columns>:not(caption)>tr>:nth-child(2n),.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000}.table-primary,.table-secondary{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000}.table-info,.table-success{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#a6c3ca;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000}.table-danger,.table-warning{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000}.table-dark,.table-light{border-color:var(--bs-table-border-color);color:var(--bs-table-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff}.table-responsive{-webkit-overflow-scrolling:touch;overflow-x:auto}@media (max-width:575.98px){.table-responsive-sm{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media (max-width:767.98px){.table-responsive-md{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media (max-width:991.98px){.table-responsive-lg{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media (max-width:1199.98px){.table-responsive-xl{-webkit-overflow-scrolling:touch;overflow-x:auto}}@media (max-width:1399.98px){.table-responsive-xxl{-webkit-overflow-scrolling:touch;overflow-x:auto}}.form-label{margin-bottom:.5rem}.col-form-label{font-size:inherit;line-height:1.5;margin-bottom:0;padding-bottom:calc(.375rem + var(--bs-border-width));padding-top:calc(.375rem + var(--bs-border-width))}.col-form-label-lg{font-size:1.25rem;padding-bottom:calc(.5rem + var(--bs-border-width));padding-top:calc(.5rem + var(--bs-border-width))}.col-form-label-sm{font-size:.875rem;padding-bottom:calc(.25rem + var(--bs-border-width));padding-top:calc(.25rem + var(--bs-border-width))}.form-text{color:var(--bs-secondary-color);font-size:.875em;margin-top:.25rem}.form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-clip:padding-box;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);color:var(--bs-body-color);display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{background-color:var(--bs-body-bg);border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);color:var(--bs-body-color);outline:0}.form-control::-webkit-date-and-time-value{height:1.5em;margin:0;min-width:85px}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::-moz-placeholder{color:var(--bs-secondary-color);opacity:1}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::file-selector-button{background-color:var(--bs-tertiary-bg);border:0 solid;border-color:inherit;border-inline-end-width:var(--bs-border-width);border-radius:0;color:var(--bs-body-color);margin:-.375rem -.75rem;margin-inline-end:.75rem;padding:.375rem .75rem;pointer-events:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0;color:var(--bs-body-color);display:block;line-height:1.5;margin-bottom:0;padding:.375rem 0;width:100%}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-left:0;padding-right:0}.form-control-sm{border-radius:var(--bs-border-radius-sm);font-size:.875rem;min-height:calc(1.5em + .5rem + var(--bs-border-width)*2);padding:.25rem .5rem}.form-control-sm::file-selector-button{margin:-.25rem -.5rem;margin-inline-end:.5rem;padding:.25rem .5rem}.form-control-lg{border-radius:var(--bs-border-radius-lg);font-size:1.25rem;min-height:calc(1.5em + 1rem + var(--bs-border-width)*2);padding:.5rem 1rem}.form-control-lg::file-selector-button{margin:-.5rem -1rem;margin-inline-end:1rem;padding:.5rem 1rem}textarea.form-control{min-height:calc(1.5em + .75rem + var(--bs-border-width)*2)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + var(--bs-border-width)*2)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + var(--bs-border-width)*2)}.form-control-color{height:calc(1.5em + .75rem + var(--bs-border-width)*2);padding:.375rem;width:3rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + var(--bs-border-width)*2)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + var(--bs-border-width)*2)}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-position:right .75rem center;background-repeat:no-repeat;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);color:var(--bs-body-color);display:block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem 2.25rem .375rem .75rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.form-select[multiple],.form-select[size]:not([size="1"]){background-image:none;padding-right:.75rem}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{border-radius:var(--bs-border-radius-sm);font-size:.875rem;padding-bottom:.25rem;padding-left:.5rem;padding-top:.25rem}.form-select-lg{border-radius:var(--bs-border-radius-lg);font-size:1.25rem;padding-bottom:.5rem;padding-left:1rem;padding-top:.5rem}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E")}.form-check{display:block;margin-bottom:.125rem;min-height:1.5rem;padding-left:1.5em}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-left:0;padding-right:1.5em;text-align:right}.form-check-reverse .form-check-input{float:right;margin-left:0;margin-right:-1.5em}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-position:50%;background-repeat:no-repeat;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);flex-shrink:0;height:1em;margin-top:.25em;-webkit-print-color-adjust:exact;print-color-adjust:exact;vertical-align:top;width:1em}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='2' fill='%23fff'/%3E%3C/svg%3E")}.form-check-input[type=checkbox]:indeterminate{--bs-form-check-bg-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3E%3C/svg%3E");background-color:#0d6efd;border-color:#0d6efd}.form-check-input:disabled{filter:none;opacity:.5;pointer-events:none}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='rgba(0, 0, 0, 0.25)'/%3E%3C/svg%3E");background-image:var(--bs-form-switch-bg);background-position:0;border-radius:2em;margin-left:-2.5em;transition:background-position .15s ease-in-out;width:2em}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%2386b7fe'/%3E%3C/svg%3E")}.form-switch .form-check-input:checked{--bs-form-switch-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E");background-position:100%}.form-switch.form-check-reverse{padding-left:0;padding-right:2.5em}.form-switch.form-check-reverse .form-check-input{margin-left:0;margin-right:-2.5em}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{clip:rect(0,0,0,0);pointer-events:none;position:absolute}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{filter:none;opacity:.65;pointer-events:none}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='rgba(255, 255, 255, 0.25)'/%3E%3C/svg%3E")}.form-range{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;height:1.5rem;padding:0;width:100%}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;height:1rem;margin-top:-.25rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.form-range::-moz-range-thumb{-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;height:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;width:1rem}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem;color:transparent;cursor:pointer;height:.5rem;width:100%}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + var(--bs-border-width)*2);line-height:1.25;min-height:calc(3.5rem + var(--bs-border-width)*2)}.form-floating>label{border:var(--bs-border-width) solid transparent;height:100%;left:0;overflow:hidden;padding:1rem .75rem;pointer-events:none;position:absolute;text-align:start;text-overflow:ellipsis;top:0;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out;white-space:nowrap;z-index:2}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-select{padding-bottom:.625rem;padding-top:1.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:not(:-moz-placeholder-shown)~label:after{background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius);content:"";height:1.5em;inset:1rem .375rem;position:absolute;z-index:-1}.form-floating>.form-control-plaintext~label:after,.form-floating>.form-control:focus~label:after,.form-floating>.form-control:not(:placeholder-shown)~label:after,.form-floating>.form-select~label:after{background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius);content:"";height:1.5em;inset:1rem .375rem;position:absolute;z-index:-1}.form-floating>.form-control:-webkit-autofill~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#6c757d}.form-floating>.form-control:disabled~label:after,.form-floating>:disabled~label:after{background-color:var(--bs-secondary-bg)}.input-group{align-items:stretch;display:flex;flex-wrap:wrap;position:relative;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{flex:1 1 auto;min-width:0;position:relative;width:1%}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{align-items:center;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);color:var(--bs-body-color);display:flex;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;white-space:nowrap}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{border-radius:var(--bs-border-radius-lg);font-size:1.25rem;padding:.5rem 1rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{border-radius:var(--bs-border-radius-sm);font-size:.875rem;padding:.25rem .5rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-bottom-right-radius:0;border-top-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:calc(var(--bs-border-width)*-1)}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-bottom-left-radius:0;border-top-left-radius:0}.valid-feedback{color:var(--bs-form-valid-color);display:none;font-size:.875em;margin-top:.25rem;width:100%}.valid-tooltip{background-color:var(--bs-success);border-radius:var(--bs-border-radius);color:#fff;display:none;font-size:.875rem;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3E%3C/svg%3E");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem);padding-right:4.125rem}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3.75rem + 1.5em)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{color:var(--bs-form-invalid-color);display:none;font-size:.875em;margin-top:.25rem;width:100%}.invalid-tooltip{background-color:var(--bs-danger);border-radius:var(--bs-border-radius);color:#fff;display:none;font-size:.875rem;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right calc(.375em + .1875rem) center;background-repeat:no-repeat;background-size:calc(.75em + .375rem) calc(.75em + .375rem);border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem);padding-right:calc(1.5em + .75rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem);padding-right:4.125rem}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3.75rem + 1.5em)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 hsla(0,0%,100%,.15),0 1px 1px rgba(0,0,0,.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb),.5);background-color:var(--bs-btn-bg);border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);color:var(--bs-btn-color);cursor:pointer;display:inline-block;font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);color:var(--bs-btn-hover-color)}.btn-check+.btn:hover{background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color);color:var(--bs-btn-color)}.btn:focus-visible{background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);box-shadow:var(--bs-btn-focus-box-shadow);color:var(--bs-btn-hover-color);outline:0}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);box-shadow:var(--bs-btn-focus-box-shadow);outline:0}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color);color:var(--bs-btn-active-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);color:var(--bs-btn-disabled-color);opacity:var(--bs-btn-disabled-opacity);pointer-events:none}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0,0,0,.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{height:auto;transition:width .35s ease;width:0}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{border-bottom:0;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:.3em solid;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;background-clip:padding-box;background-color:var(--bs-dropdown-bg);border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius);color:var(--bs-dropdown-color);display:none;font-size:var(--bs-dropdown-font-size);list-style:none;margin:0;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);position:absolute;text-align:left;z-index:var(--bs-dropdown-zindex)}.dropdown-menu[data-bs-popper]{left:0;margin-top:var(--bs-dropdown-spacer);top:100%}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{left:auto;right:0}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{left:auto;right:0}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{left:auto;right:0}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{left:auto;right:0}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{left:auto;right:0}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{left:0;right:auto}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{left:auto;right:0}}.dropup .dropdown-menu[data-bs-popper]{bottom:100%;margin-bottom:var(--bs-dropdown-spacer);margin-top:0;top:auto}.dropup .dropdown-toggle:after{border-bottom:.3em solid;border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:0;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{left:100%;margin-left:var(--bs-dropdown-spacer);margin-top:0;right:auto;top:0}.dropend .dropdown-toggle:after{border-bottom:.3em solid transparent;border-left:.3em solid;border-right:0;border-top:.3em solid transparent;content:"";display:inline-block;margin-left:.255em;vertical-align:.255em}.dropend .dropdown-toggle:empty:after{margin-left:0}.dropend .dropdown-toggle:after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{left:auto;margin-right:var(--bs-dropdown-spacer);margin-top:0;right:100%;top:0}.dropstart .dropdown-toggle:after{content:"";display:inline-block;display:none;margin-left:.255em;vertical-align:.255em}.dropstart .dropdown-toggle:before{border-bottom:.3em solid transparent;border-right:.3em solid;border-top:.3em solid transparent;content:"";display:inline-block;margin-right:.255em;vertical-align:.255em}.dropstart .dropdown-toggle:empty:after{margin-left:0}.dropstart .dropdown-toggle:before{vertical-align:0}.dropdown-divider{border-top:1px solid var(--bs-dropdown-divider-bg);height:0;margin:var(--bs-dropdown-divider-margin-y) 0;opacity:1;overflow:hidden}.dropdown-item{background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0);clear:both;color:var(--bs-dropdown-link-color);display:block;font-weight:400;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);text-align:inherit;text-decoration:none;white-space:nowrap;width:100%}.dropdown-item:focus,.dropdown-item:hover{background-color:var(--bs-dropdown-link-hover-bg);color:var(--bs-dropdown-link-hover-color)}.dropdown-item.active,.dropdown-item:active{background-color:var(--bs-dropdown-link-active-bg);color:var(--bs-dropdown-link-active-color);text-decoration:none}.dropdown-item.disabled,.dropdown-item:disabled{background-color:transparent;color:var(--bs-dropdown-link-disabled-color);pointer-events:none}.dropdown-menu.show{display:block}.dropdown-header{color:var(--bs-dropdown-header-color);display:block;font-size:.875rem;margin-bottom:0;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);white-space:nowrap}.dropdown-item-text{color:var(--bs-dropdown-link-color);display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:hsla(0,0%,100%,.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{display:inline-flex;position:relative;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{flex:1 1 auto;position:relative}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(var(--bs-border-width)*-1)}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-bottom-left-radius:0;border-top-left-radius:0}.dropdown-toggle-split{padding-left:.5625rem;padding-right:.5625rem}.dropdown-toggle-split:after,.dropend .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropstart .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.btn-group-vertical{align-items:flex-start;flex-direction:column;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(var(--bs-border-width)*-1)}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;list-style:none;margin-bottom:0;padding-left:0}.nav-link{background:0 0;border:0;color:var(--bs-nav-link-color);display:block;font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{box-shadow:0 0 0 .25rem rgba(13,110,253,.25);outline:0}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);cursor:default;pointer-events:none}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius);margin-bottom:calc(var(--bs-nav-tabs-border-width)*-1)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:var(--bs-nav-tabs-link-hover-border-color);isolation:isolate}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color);color:var(--bs-nav-tabs-link-active-color)}.nav-tabs .dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;margin-top:calc(var(--bs-nav-tabs-border-width)*-1)}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{background-color:var(--bs-nav-pills-link-active-bg);color:var(--bs-nav-pills-link-active-color)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{border-bottom:var(--bs-nav-underline-border-width) solid transparent;padding-left:0;padding-right:0}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{border-bottom-color:currentcolor;color:var(--bs-nav-underline-link-active-color);font-weight:700}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb),0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb),0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb),0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb),1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb),1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb),1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(33, 37, 41, 0.75)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb),0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);position:relative}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{align-items:center;display:flex;flex-wrap:inherit;justify-content:space-between}.navbar-brand{color:var(--bs-navbar-brand-color);font-size:var(--bs-navbar-brand-font-size);margin-right:var(--bs-navbar-brand-margin-end);padding-bottom:var(--bs-navbar-brand-padding-y);padding-top:var(--bs-navbar-brand-padding-y);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;list-style:none;margin-bottom:0;padding-left:0}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{color:var(--bs-navbar-color);padding-bottom:.5rem;padding-top:.5rem}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{align-items:center;flex-basis:100%;flex-grow:1}.navbar-toggler{background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);color:var(--bs-navbar-color);font-size:var(--bs-navbar-toggler-font-size);line-height:1;padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width);outline:0;text-decoration:none}.navbar-toggler-icon{background-image:var(--bs-navbar-toggler-icon-bg);background-position:50%;background-repeat:no-repeat;background-size:100%;display:inline-block;height:1.5em;vertical-align:middle;width:1.5em}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-left:var(--bs-navbar-nav-link-padding-x);padding-right:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{background-color:transparent!important;border:0!important;flex-grow:1;height:auto!important;position:static;transform:none!important;transition:none;visibility:visible!important;width:auto!important;z-index:auto}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;overflow-y:visible;padding:0}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:hsla(0,0%,100%,.55);--bs-navbar-hover-color:hsla(0,0%,100%,.75);--bs-navbar-disabled-color:hsla(0,0%,100%,.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:hsla(0,0%,100%,.1)}.navbar-dark,.navbar[data-bs-theme=dark],[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.55)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb),0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;word-wrap:break-word;background-clip:border-box;background-color:var(--bs-card-bg);border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius);color:var(--bs-body-color);display:flex;flex-direction:column;height:var(--bs-card-height);min-width:0;position:relative}.card>hr{margin-left:0;margin-right:0}.card>.list-group{border-bottom:inherit;border-top:inherit}.card>.list-group:first-child{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius);border-top-width:0}.card>.list-group:last-child{border-bottom-left-radius:var(--bs-card-inner-border-radius);border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{color:var(--bs-card-color);flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x)}.card-title{color:var(--bs-card-title-color);margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{color:var(--bs-card-subtitle-color);margin-top:calc(var(--bs-card-title-spacer-y)*-.5)}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color);color:var(--bs-card-cap-color);margin-bottom:0;padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color);color:var(--bs-card-cap-color);padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{border-bottom:0;margin-bottom:calc(var(--bs-card-cap-padding-y)*-1);margin-left:calc(var(--bs-card-cap-padding-x)*-.5);margin-right:calc(var(--bs-card-cap-padding-x)*-.5)}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-left:calc(var(--bs-card-cap-padding-x)*-.5);margin-right:calc(var(--bs-card-cap-padding-x)*-.5)}.card-img-overlay{border-radius:var(--bs-card-inner-border-radius);bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);position:absolute;right:0;top:0}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-left-radius:var(--bs-card-inner-border-radius);border-bottom-right-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{border-left:0;margin-left:0}.card-group>.card:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23212529' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23052c65' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E");--bs-accordion-btn-focus-border-color:#86b7fe;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13,110,253,.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{align-items:center;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;color:var(--bs-accordion-btn-color);display:flex;font-size:1rem;overflow-anchor:none;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);position:relative;text-align:left;transition:var(--bs-accordion-transition);width:100%}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(var(--bs-accordion-border-width)*-1) 0 var(--bs-accordion-border-color);color:var(--bs-accordion-active-color)}.accordion-button:not(.collapsed):after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button:after{background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);content:"";flex-shrink:0;height:var(--bs-accordion-btn-icon-width);margin-left:auto;transition:var(--bs-accordion-btn-icon-transition);width:var(--bs-accordion-btn-icon-width)}@media (prefers-reduced-motion:reduce){.accordion-button:after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{border-color:var(--bs-accordion-btn-focus-border-color);box-shadow:var(--bs-accordion-btn-focus-box-shadow);outline:0;z-index:3}.accordion-header{margin-bottom:0}.accordion-item{background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color);color:var(--bs-accordion-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-left-radius:var(--bs-accordion-border-radius);border-bottom-right-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-left-radius:var(--bs-accordion-inner-border-radius);border-bottom-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-left-radius:var(--bs-accordion-border-radius);border-bottom-right-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-left:0;border-radius:0;border-right:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button:after{--bs-accordion-btn-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%236ea8fe' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E");--bs-accordion-btn-active-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%236ea8fe' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius);display:flex;flex-wrap:wrap;font-size:var(--bs-breadcrumb-font-size);list-style:none;margin-bottom:var(--bs-breadcrumb-margin-bottom);padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item:before{color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider,"/");float:left;padding-right:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13,110,253,.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;list-style:none;padding-left:0}.page-link{background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);color:var(--bs-pagination-color);display:block;font-size:var(--bs-pagination-font-size);padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);position:relative;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color);color:var(--bs-pagination-hover-color);z-index:2}.page-link:focus{background-color:var(--bs-pagination-focus-bg);box-shadow:var(--bs-pagination-focus-box-shadow);color:var(--bs-pagination-focus-color);outline:0;z-index:3}.active>.page-link,.page-link.active{background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color);color:var(--bs-pagination-active-color);z-index:3}.disabled>.page-link,.page-link.disabled{background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color);color:var(--bs-pagination-disabled-color);pointer-events:none}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width)*-1)}.page-item:first-child .page-link{border-bottom-left-radius:var(--bs-pagination-border-radius);border-top-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-bottom-right-radius:var(--bs-pagination-border-radius);border-top-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);border-radius:var(--bs-badge-border-radius);color:var(--bs-badge-color);display:inline-block;font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);text-align:center;vertical-align:baseline;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius);color:var(--bs-alert-color);margin-bottom:var(--bs-alert-margin-bottom);padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);position:relative}.alert-heading{color:inherit}.alert-link{color:var(--bs-alert-link-color);font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{padding:1.25rem 1rem;position:absolute;right:0;top:0;z-index:2}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius);display:flex;font-size:var(--bs-progress-font-size);height:var(--bs-progress-height);overflow:hidden}.progress-bar{background-color:var(--bs-progress-bar-bg);color:var(--bs-progress-bar-color);display:flex;flex-direction:column;justify-content:center;overflow:hidden;text-align:center;transition:var(--bs-progress-bar-transition);white-space:nowrap}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;border-radius:var(--bs-list-group-border-radius);display:flex;flex-direction:column;margin-bottom:0;padding-left:0}.list-group-numbered{counter-reset:section;list-style-type:none}.list-group-numbered>.list-group-item:before{content:counters(section,".") ". ";counter-increment:section}.list-group-item-action{color:var(--bs-list-group-action-color);text-align:inherit;width:100%}.list-group-item-action:focus,.list-group-item-action:hover{background-color:var(--bs-list-group-action-hover-bg);color:var(--bs-list-group-action-hover-color);text-decoration:none;z-index:1}.list-group-item-action:active{background-color:var(--bs-list-group-action-active-bg);color:var(--bs-list-group-action-active-color)}.list-group-item{background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color);color:var(--bs-list-group-color);display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);position:relative;text-decoration:none}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{background-color:var(--bs-list-group-disabled-bg);color:var(--bs-list-group-disabled-color);pointer-events:none}.list-group-item.active{background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color);color:var(--bs-list-group-active-color);z-index:2}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{border-top-width:var(--bs-list-group-border-width);margin-top:calc(var(--bs-list-group-border-width)*-1)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-md>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-right-radius:var(--bs-list-group-border-radius)}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-left-width:0;border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{border-left-width:var(--bs-list-group-border-width);margin-left:calc(var(--bs-list-group-border-width)*-1)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3E%3C/svg%3E");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13,110,253,.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;box-sizing:content-box;height:1em;opacity:var(--bs-btn-close-opacity);padding:.25em;width:1em}.btn-close,.btn-close:hover{color:var(--bs-btn-close-color)}.btn-close:hover{opacity:var(--bs-btn-close-hover-opacity);text-decoration:none}.btn-close:focus{box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity);outline:0}.btn-close.disabled,.btn-close:disabled{opacity:var(--bs-btn-close-disabled-opacity);pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.btn-close-white,[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb),0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb),0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);background-clip:padding-box;background-color:var(--bs-toast-bg);border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);border-radius:var(--bs-toast-border-radius);box-shadow:var(--bs-toast-box-shadow);color:var(--bs-toast-color);font-size:var(--bs-toast-font-size);max-width:100%;pointer-events:auto;width:var(--bs-toast-max-width)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;max-width:100%;pointer-events:none;position:absolute;width:-moz-max-content;width:max-content;z-index:var(--bs-toast-zindex)}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{align-items:center;background-clip:padding-box;background-color:var(--bs-toast-header-bg);border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));color:var(--bs-toast-header-color);display:flex;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x)}.toast-header .btn-close{margin-left:var(--bs-toast-padding-x);margin-right:calc(var(--bs-toast-padding-x)*-.5)}.toast-body{word-wrap:break-word;padding:var(--bs-toast-padding-x)}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);display:none;height:100%;left:0;outline:0;overflow-x:hidden;overflow-y:auto;position:fixed;top:0;width:100%;z-index:var(--bs-modal-zindex)}.modal-dialog{margin:var(--bs-modal-margin);pointer-events:none;position:relative;width:auto}.modal.fade .modal-dialog{transform:translateY(-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin)*2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{align-items:center;display:flex;min-height:calc(100% - var(--bs-modal-margin)*2)}.modal-content{background-clip:padding-box;background-color:var(--bs-modal-bg);border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);color:var(--bs-modal-color);display:flex;flex-direction:column;outline:0;pointer-events:auto;position:relative;width:100%}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;background-color:var(--bs-backdrop-bg);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:var(--bs-backdrop-zindex)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{align-items:center;border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius);display:flex;flex-shrink:0;justify-content:space-between;padding:var(--bs-modal-header-padding)}.modal-header .btn-close{margin:calc(var(--bs-modal-header-padding-y)*-.5) calc(var(--bs-modal-header-padding-x)*-.5) calc(var(--bs-modal-header-padding-y)*-.5) auto;padding:calc(var(--bs-modal-header-padding-y)*.5) calc(var(--bs-modal-header-padding-x)*.5)}.modal-title{line-height:var(--bs-modal-title-line-height);margin-bottom:0}.modal-body{flex:1 1 auto;padding:var(--bs-modal-padding);position:relative}.modal-footer{align-items:center;background-color:var(--bs-modal-footer-bg);border-bottom-left-radius:var(--bs-modal-inner-border-radius);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);display:flex;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap)*.5)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap)*.5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{margin-left:auto;margin-right:auto;max-width:var(--bs-modal-width)}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-sm-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-md-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-lg-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-xl-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{height:100%;margin:0;max-width:none;width:100vw}.modal-fullscreen-xxl-down .modal-content{border:0;border-radius:0;height:100%}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;word-wrap:break-word;display:block;font-family:var(--bs-font-sans-serif);font-size:var(--bs-tooltip-font-size);font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;margin:var(--bs-tooltip-margin);opacity:0;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:var(--bs-tooltip-zindex)}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;height:var(--bs-tooltip-arrow-height);width:var(--bs-tooltip-arrow-width)}.tooltip .tooltip-arrow:before{border-color:transparent;border-style:solid;content:"";position:absolute}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(var(--bs-tooltip-arrow-height)*-1)}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow:before,.bs-tooltip-top .tooltip-arrow:before{border-top-color:var(--bs-tooltip-bg);border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;top:-1px}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{height:var(--bs-tooltip-arrow-width);left:calc(var(--bs-tooltip-arrow-height)*-1);width:var(--bs-tooltip-arrow-height)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow:before,.bs-tooltip-end .tooltip-arrow:before{border-right-color:var(--bs-tooltip-bg);border-width:calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;right:-1px}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(var(--bs-tooltip-arrow-height)*-1)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow:before,.bs-tooltip-bottom .tooltip-arrow:before{border-bottom-color:var(--bs-tooltip-bg);border-width:0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);bottom:-1px}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{height:var(--bs-tooltip-arrow-width);right:calc(var(--bs-tooltip-arrow-height)*-1);width:var(--bs-tooltip-arrow-height)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow:before,.bs-tooltip-start .tooltip-arrow:before{border-left-color:var(--bs-tooltip-bg);border-width:calc(var(--bs-tooltip-arrow-width)*.5) 0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);left:-1px}.tooltip-inner{background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius);color:var(--bs-tooltip-color);max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);text-align:center}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);word-wrap:break-word;background-clip:padding-box;background-color:var(--bs-popover-bg);border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius);display:block;font-family:var(--bs-font-sans-serif);font-size:var(--bs-popover-font-size);font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;max-width:var(--bs-popover-max-width);text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;z-index:var(--bs-popover-zindex)}.popover .popover-arrow{display:block;height:var(--bs-popover-arrow-height);width:var(--bs-popover-arrow-width)}.popover .popover-arrow:after,.popover .popover-arrow:before{border:0 solid transparent;content:"";display:block;position:absolute}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:after,.bs-popover-top>.popover-arrow:before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:before{border-top-color:var(--bs-popover-arrow-border);bottom:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-top>.popover-arrow:after{border-top-color:var(--bs-popover-bg);bottom:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{height:var(--bs-popover-arrow-width);left:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:after,.bs-popover-end>.popover-arrow:before{border-width:calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:before{border-right-color:var(--bs-popover-arrow-border);left:0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-end>.popover-arrow:after{border-right-color:var(--bs-popover-bg);left:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:before{border-width:0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:before{border-bottom-color:var(--bs-popover-arrow-border);top:0}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:after{border-bottom-color:var(--bs-popover-bg);top:var(--bs-popover-border-width)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg);content:"";display:block;left:50%;margin-left:calc(var(--bs-popover-arrow-width)*-.5);position:absolute;top:0;width:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{height:var(--bs-popover-arrow-width);right:calc((var(--bs-popover-arrow-height))*-1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:after,.bs-popover-start>.popover-arrow:before{border-width:calc(var(--bs-popover-arrow-width)*.5) 0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:before{border-left-color:var(--bs-popover-arrow-border);right:0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-start>.popover-arrow:after{border-left-color:var(--bs-popover-bg);right:var(--bs-popover-border-width)}.popover-header{background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius);color:var(--bs-popover-header-color);font-size:var(--bs-popover-header-font-size);margin-bottom:0;padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x)}.popover-header:empty{display:none}.popover-body{color:var(--bs-popover-body-color);padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{overflow:hidden;position:relative;width:100%}.carousel-inner:after{clear:both;content:"";display:block}.carousel-item{backface-visibility:hidden;display:none;float:left;margin-right:-100%;position:relative;transition:transform .6s ease-in-out;width:100%}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transform:none;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{opacity:1;z-index:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{opacity:0;transition:opacity 0s .6s;z-index:0}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{align-items:center;background:0 0;border:0;bottom:0;color:#fff;display:flex;justify-content:center;opacity:.5;padding:0;position:absolute;text-align:center;top:0;transition:opacity .15s ease;width:15%;z-index:1}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;opacity:.9;outline:0;text-decoration:none}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{background-position:50%;background-repeat:no-repeat;background-size:100% 100%;display:inline-block;height:2rem;width:2rem}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E")}.carousel-indicators{bottom:0;display:flex;justify-content:center;left:0;margin-bottom:1rem;margin-left:15%;margin-right:15%;padding:0;position:absolute;right:0;z-index:2}.carousel-indicators [data-bs-target]{background-clip:padding-box;background-color:#fff;border:0;border-bottom:10px solid transparent;border-top:10px solid transparent;box-sizing:content-box;cursor:pointer;flex:0 1 auto;height:3px;margin-left:3px;margin-right:3px;opacity:.5;padding:0;text-indent:-999px;transition:opacity .6s ease;width:30px}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{bottom:1.25rem;color:#fff;left:15%;padding-bottom:1.25rem;padding-top:1.25rem;position:absolute;right:15%;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark] .carousel .carousel-control-prev-icon,[data-bs-theme=dark].carousel .carousel-control-next-icon,[data-bs-theme=dark].carousel .carousel-control-prev-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target],[data-bs-theme=dark].carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption,[data-bs-theme=dark].carousel .carousel-caption{color:#000}.spinner-border,.spinner-grow{animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);border-radius:50%;display:inline-block;height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);width:var(--bs-spinner-width)}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border-right-color:currentcolor;border:var(--bs-spinner-border-width) solid;border-right:var(--bs-spinner-border-width) solid transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-sm.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-sm.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom,.offcanvas-sm.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-sm.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (max-width:767.98px){.offcanvas-md{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-md.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-md.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom,.offcanvas-md.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-md.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (max-width:991.98px){.offcanvas-lg{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-lg.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-lg.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom,.offcanvas-lg.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-lg.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (max-width:1199.98px){.offcanvas-xl{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-xl.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-xl.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom,.offcanvas-xl.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-xl.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}@media (max-width:1399.98px){.offcanvas-xxl{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas-xxl.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas-xxl.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom,.offcanvas-xxl.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas-xxl.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{background-color:transparent!important;display:flex;flex-grow:0;overflow-y:visible;padding:0}}.offcanvas{background-clip:padding-box;background-color:var(--bs-offcanvas-bg);bottom:0;color:var(--bs-offcanvas-color);display:flex;flex-direction:column;max-width:100%;outline:0;position:fixed;transition:var(--bs-offcanvas-transition);visibility:hidden;z-index:var(--bs-offcanvas-zindex)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);left:0;top:0;transform:translateX(-100%);width:var(--bs-offcanvas-width)}.offcanvas.offcanvas-end{border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);right:0;top:0;transform:translateX(100%);width:var(--bs-offcanvas-width)}.offcanvas.offcanvas-top{border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);top:0;transform:translateY(-100%)}.offcanvas.offcanvas-bottom,.offcanvas.offcanvas-top{height:var(--bs-offcanvas-height);left:0;max-height:100%;right:0}.offcanvas.offcanvas-bottom{border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{background-color:#000;height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:1040}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{align-items:center;display:flex;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{margin-bottom:calc(var(--bs-offcanvas-padding-y)*-.5);margin-right:calc(var(--bs-offcanvas-padding-x)*-.5);margin-top:calc(var(--bs-offcanvas-padding-y)*-.5);padding:calc(var(--bs-offcanvas-padding-y)*.5) calc(var(--bs-offcanvas-padding-x)*.5)}.offcanvas-title{line-height:var(--bs-offcanvas-title-line-height);margin-bottom:0}.offcanvas-body{flex-grow:1;overflow-y:auto;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.placeholder{background-color:currentcolor;cursor:wait;display:inline-block;min-height:1em;opacity:.5;vertical-align:middle}.placeholder.btn:before{content:"";display:inline-block}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{animation:placeholder-wave 2s linear infinite;-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%}@keyframes placeholder-wave{to{-webkit-mask-position:-200% 0;mask-position:-200% 0}}.clearfix:after{clear:both;content:"";display:block}.text-bg-primary{background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-secondary{background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-success{background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-info{background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important;color:#000!important}.text-bg-warning{background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important;color:#000!important}.text-bg-danger{background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.text-bg-light{background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important;color:#000!important}.text-bg-dark{background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important;color:#fff!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(10,88,202,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(86,94,100,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(20,108,67,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(61,213,243,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(255,205,57,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(176,42,55,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(249,250,251,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(26,30,33,var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,.75))!important}.focus-ring:focus{box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color);outline:0}.icon-link{align-items:center;backface-visibility:hidden;display:inline-flex;gap:.375rem;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,.5));text-underline-offset:.25em}.icon-link>.bi{fill:currentcolor;flex-shrink:0;height:1em;transition:transform .2s ease-in-out;width:1em}@media (prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio:before{content:"";display:block;padding-top:var(--bs-aspect-ratio)}.ratio>*{height:100%;left:0;position:absolute;top:0;width:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{top:0}.fixed-bottom,.fixed-top{left:0;position:fixed;right:0;z-index:1030}.fixed-bottom{bottom:0}.sticky-top{top:0}.sticky-bottom,.sticky-top{position:sticky;z-index:1020}.sticky-bottom{bottom:0}@media (min-width:576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}.sticky-sm-bottom{bottom:0;position:sticky;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:sticky;top:0;z-index:1020}.sticky-md-bottom{bottom:0;position:sticky;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}.sticky-lg-bottom{bottom:0;position:sticky;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}.sticky-xl-bottom{bottom:0;position:sticky;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{bottom:0;position:sticky;z-index:1020}}.hstack{align-items:center;flex-direction:row}.hstack,.vstack{align-self:stretch;display:flex}.vstack{flex:1 1 auto;flex-direction:column}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;white-space:nowrap!important;width:1px!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.stretched-link:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:1}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{align-self:stretch;background-color:currentcolor;display:inline-block;min-height:1em;opacity:.25;width:var(--bs-border-width)}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb),var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb),var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb),var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb),var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb),var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb),var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb),var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb),var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-left:0!important;margin-right:0!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-3{margin-left:1rem!important;margin-right:1rem!important}.mx-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-5{margin-left:3rem!important;margin-right:3rem!important}.mx-auto{margin-left:auto!important;margin-right:auto!important}.my-0{margin-bottom:0!important;margin-top:0!important}.my-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-left:0!important;padding-right:0!important}.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-3{padding-left:1rem!important;padding-right:1rem!important}.px-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-5{padding-left:3rem!important;padding-right:3rem!important}.py-0{padding-bottom:0!important;padding-top:0!important}.py-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:hsla(0,0%,100%,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10,.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25,.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50,.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75,.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100,.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1,.link-offset-1-hover:hover{text-underline-offset:.125em!important}.link-offset-2,.link-offset-2-hover:hover{text-underline-offset:.25em!important}.link-offset-3,.link-offset-3-hover:hover{text-underline-offset:.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0,.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10,.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25,.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50,.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75,.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100,.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-bottom-right-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-bottom-right-radius:0!important;border-top-right-radius:0!important}.rounded-end-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-bottom-right-radius:50%!important;border-top-right-radius:50%!important}.rounded-end-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-left-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.rounded-bottom-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-left-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-bottom-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-left:0!important;margin-right:0!important}.mx-sm-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-sm-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-sm-3{margin-left:1rem!important;margin-right:1rem!important}.mx-sm-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-sm-5{margin-left:3rem!important;margin-right:3rem!important}.mx-sm-auto{margin-left:auto!important;margin-right:auto!important}.my-sm-0{margin-bottom:0!important;margin-top:0!important}.my-sm-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-sm-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-sm-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-sm-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-sm-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-sm-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-left:0!important;padding-right:0!important}.px-sm-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-sm-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-sm-3{padding-left:1rem!important;padding-right:1rem!important}.px-sm-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-sm-5{padding-left:3rem!important;padding-right:3rem!important}.py-sm-0{padding-bottom:0!important;padding-top:0!important}.py-sm-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-sm-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-sm-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-sm-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-sm-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-left:0!important;margin-right:0!important}.mx-md-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-md-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-md-3{margin-left:1rem!important;margin-right:1rem!important}.mx-md-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-md-5{margin-left:3rem!important;margin-right:3rem!important}.mx-md-auto{margin-left:auto!important;margin-right:auto!important}.my-md-0{margin-bottom:0!important;margin-top:0!important}.my-md-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-md-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-md-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-md-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-md-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-md-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-left:0!important;padding-right:0!important}.px-md-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-md-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-md-3{padding-left:1rem!important;padding-right:1rem!important}.px-md-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-md-5{padding-left:3rem!important;padding-right:3rem!important}.py-md-0{padding-bottom:0!important;padding-top:0!important}.py-md-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-md-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-md-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-md-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-md-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-left:0!important;margin-right:0!important}.mx-lg-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-lg-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-lg-3{margin-left:1rem!important;margin-right:1rem!important}.mx-lg-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-lg-5{margin-left:3rem!important;margin-right:3rem!important}.mx-lg-auto{margin-left:auto!important;margin-right:auto!important}.my-lg-0{margin-bottom:0!important;margin-top:0!important}.my-lg-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-lg-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-lg-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-lg-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-lg-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-lg-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-left:0!important;padding-right:0!important}.px-lg-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-lg-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-lg-3{padding-left:1rem!important;padding-right:1rem!important}.px-lg-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-lg-5{padding-left:3rem!important;padding-right:3rem!important}.py-lg-0{padding-bottom:0!important;padding-top:0!important}.py-lg-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-lg-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-lg-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-lg-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-lg-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-left:0!important;margin-right:0!important}.mx-xl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xl-auto{margin-left:auto!important;margin-right:auto!important}.my-xl-0{margin-bottom:0!important;margin-top:0!important}.my-xl-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-xl-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-xl-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-xl-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-xl-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-xl-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-left:0!important;padding-right:0!important}.px-xl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xl-0{padding-bottom:0!important;padding-top:0!important}.py-xl-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-xl-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-xl-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-xl-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-xl-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-left:0!important;margin-right:0!important}.mx-xxl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xxl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xxl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xxl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xxl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xxl-auto{margin-left:auto!important;margin-right:auto!important}.my-xxl-0{margin-bottom:0!important;margin-top:0!important}.my-xxl-1{margin-bottom:.25rem!important;margin-top:.25rem!important}.my-xxl-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.my-xxl-3{margin-bottom:1rem!important;margin-top:1rem!important}.my-xxl-4{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.my-xxl-5{margin-bottom:3rem!important;margin-top:3rem!important}.my-xxl-auto{margin-bottom:auto!important;margin-top:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-left:0!important;padding-right:0!important}.px-xxl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xxl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xxl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xxl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xxl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xxl-0{padding-bottom:0!important;padding-top:0!important}.py-xxl-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.py-xxl-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.py-xxl-3{padding-bottom:1rem!important;padding-top:1rem!important}.py-xxl-4{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.py-xxl-5{padding-bottom:3rem!important;padding-top:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} \ No newline at end of file diff --git a/public/vikon_core/assets/fonts/comic.ttf b/public/vikon_core/assets/fonts/comic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8237d1f531f65e2fb2e1424a6b45820650fb34f4 GIT binary patch literal 127596 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

c=J(BK%#4{*EEjzx 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

8#8wNW+`D|d_HqJDLsX~ZOu zt2q&9T8URA(CV*ZZ`D(JZjc_Kk3fm1)auMThn#zyhnz>9$DBf_>xMyQVJGbbH4IDu z9wV?MPECWmc!34}?HXc&lv3~|?=bRzifYK7llu={ee25?ZNH=5We%v*SB(r0EM2%S z)4aL5(iOk+>fB|QfB5c4U)QD=xzi3s=(&e>?CY9i&4M;;Z_dEZu7-;LF6b7sKvZXS zzTO8@(UR7|k$?~ci z?huK{-pEjdWFz6o`wGBQ8^ZGG8Vg1BVHMJov*P3Hn)Jm1m&$! zgAFQaNQ`$Ao*b%0v{Py!Iak))c6j0Y*Ib8;pKs1Bm#He}4)CUjAAbJQg(-VC=nzD@ zcTt;ex`}`KQCWpIx-=F)aQ$frZ8bSt&;vL2ueg?%y!qDNpIDTQmC7eJZ=E*}^Y&ug z^FV8W0v_Un{1dIBW@V#mg>r>!Gdr%>T0QQ#pFOHLT6NTMOfjjLQm}Kxt?V2}vvZNC zk6r9ojPFBX)^BtiRghjI%N4DrS`fP?thRS6Mkxm6{_&(D78IKvrdoW2tzD z;(+2o`ay?K0n~(6pBznDpu}}I{UrT9Jp*Uzx;dZenCZCb18C$Ok|GwW2gjie=%9~r zOXJWD6!wk#j{7KRv@cHVoGj`=k|w546eqB=3Q-4K+E%J)#da|^TfmB)3?WmEn(%6epTIb9V^@Jb?RT>-fy=KlS<)9hO z=_8WFD(@=XhwmqP)Pw3V^=|b+^%3=x>Q~hwbuA%eh2ug>D7D&-oxgC5|;Q!C~!mYd)BD}O#*2{N&zy2 zyCW_*QB>d?Gxccwk-7GP7hzhjqRW>eHPlYqswamisiAMp>4VHJ{#aHz+%6MP^0V20 zG`zC5H|7;dFTVpRkX^iDB|~vTpN#HaF@(7&HT@p-4NVYk(2$4nqe^v?nshPkb!1rG zSACIsq;^%^9`#YRP^)k&+%Q?uS{GNut79d#lsW4sPKUlOcxIUjBv!+isoIWF{Rm;N2R)7NzZN6pGhetYH8U5lL$j~s6g zQ}J7dp8f6NqexxcWm~7w@h`oyrnqtAs=+>~M(^!IPx8m!+I??#QCZc~?;xq?cT5it z|NR7#J@9BaOl_XC?Eu<+#n$I;xbfoA)$9LYfjUnd^?03*3z{GjdS!lCT1nO`>+LWi zrZqgjez*Lf{0Khij8Lg0Tv*^F6!IEQZbCh#LDNN*yGxz!PnupeoiTj{c>$73Rd7e5 zPe$L5o{7>?HXF|7v%T4&?09xh_E7d{_IUP#tR#yIJ#Y-GEHgknjD16FDYbIm`j+ia zscHebM`oc;4ynpPE#R^;#VoTX$wHP$D4;%=1747lS-yKX(r-1TeOWj?m!gEKlz%>) zLL)$E{!60|W`hC|oR~ppvR(6UyP;@UYj}B6`a%AR)-30hRab4lnLKk@ATj{M;g+nJ zJ9_bkjY~FeSl{)`s~>FXS4e%hy8h{z|3$CDS@IIXK`hG01sqYWtQJ^ZVOOu~xQpK7 zI^;U)qAEBF2E^+*xy|AVxpJ=EF4`h}RZ8|scY_LXVbe34aKMfLj_P3r5(3Wv3lkcYCbu2(mt8`tg8Rp@ZS1e6`V@KT)a=g>M<#7<1{KdwG5L8X=GjJP`4VaFks z(him*vFN{H1u)X8l>E&OVf+kSztKODYt$zZ~B$Glv#N zxai{luJVPL3h)Z`UZOfW`c!I%BoSDptEj+?0f&*3*X;U@&F#sVFMa0McjSDjRR{i3 zyWsFmHQY4|Q0Ic%(bc!s?5M$9QoFO3f8|F%T65WN?OC7QcIW~Am;aUX;_T{=W0l_wexD{3!hW?KAtB zKhk|LU*^~OM?j{UW4Ty!Pi1R!U-PJW%s$e*wOJCb3^%r$`^_|*&C_VDv^LTeT(gTnr|I!J<|GQ>#MErx1MSJs#V--&v15*2(w`;jAk1TGht$`b#8cW ze(uoR@wvz5emz%&%_ig)1dtz2>dNpe;A&X0^Qib!@1#- z0u;dEXXoV~5V=PH#m>UnCS70&sBb7m`pddPql;tND&2ujRA~jw-uZBrlU=O0dtIxB zs*#{th1sF5y0vX93rT|p--K2*;%O9<(Rb$Dl}_A#(L)VVvnfbr7A)TQ7K*ntEzPAI z%a`-t-Mu=POa`~3Uu|ETwzloldoo{e)$8>>4x!AKnb=hPx6NKvuV!@J6F+Qkf5!RU zFf1ASEA0Vce;OEeQNf;V0OOnZ$zu&d$;g0*ECK zrc6Mb)ww{zvI;HhAPX*k0k2LYgj_v{&4E6NNha(aA6XWKh?O)E2*xYT!lZv$1@-V# zM{@xh1(I`?f4pVHbd~9&E4RPsN!N#}FR8{N0}rdwhSk6eqYS_rF^b6H1bNc>C2t!6n!I>#f!EDQaTRZ8yzt>}l#>)47O|r7t`1r_UdM z_xYPY_~fo1Q#;Z16F1y2uh6ydAi4r$u5HsVQD4)YU<2!kh52~9vo+Z7gqAWVXHuGi z93db~0yrhMN<;a*;D#TB5mjL>Z|$`XSt$Z0M_a9wwd92Z5`ZdCT%8A<+aYMMg~}A{ zr~rDNt?*PSASPT&)xkc(D$aYNupDqjA%L%)txhAO!5_Lw0k?u&d)zs) z^nm>b21FVQIExFLaEcN`L?aSFLhSn5s(5f297|uR>T~@1>Kh(-1UV9>fX$ocpMPO_ zS6k0@gTXK*Q`aX@n%{Hki6FNsSQtC4o7jE|xt@BC47l??{#Spr-MRCTtsV1eYIqz~ zA}Br*faG2~^Hb_px*FEJEYIno0nY&IlUUR&RPkED;+=2(8-m0ntCvXkDJ*P=&9Ob~ zAUnni*np*60R1g4fG(x8%hO7rhIJCcxVfp5Clz=q39J(on+Mh=R6&^<^aFrS!)mOg z)Tmp8#XgFp7mkIpkgEBvXR4w_DJz?DTd7hox&>>)h+Tmq<6cu5jJtl0i|3H$=d= ztYEkb*GG(3-Aao^E(;B#V=OS^<5eh23)l5RNw>fX1wnhN4nawfg;PpWE{I+9``7xf z(%zyK2!f&z?ciil5$BKQ6GMqT2`Zr-@*~2}!ldl5f80Og7x+`-X@vVAu?2t%Rm|_x zlQ?k&qKoSka}y_VzbUworNBS72ADLU&&#kEGsk~ms91D1W0HtNJ!*+)B^Xef(8?v9 zKfDK3n}0uk-}PIbzGB;*Ij^NozpzldFkgIS&6V7|6B#5*`oe)kRRU^x4f9oz{BjB7 zYa4y@z6H%eZrGa%>*P|kId@H1XZCOt|J85oG$^?m$Vk^>bIp|7DdDr61iL*t>Np<|&>L&74qpjgpE3o_t zHYBKpw0!!hVB}*6Y~AiA+bEfIaWJKbJm&T%ZgNFaSyrs>2$tp#ZJ0Smy-)k0qO&(& zBas{B0eKpVfH^q)w^9-c2y_C2)yye0N1#^P=c*OBxE#<7zOf1bH~>}dP__AQHvk6^ zpfb0l2(V2mn=KrY1113LKfAlwpux}-P^x-SJ~_)|WBxofjKZmZUHHKy+Cjx)r@^ zQ2SC1(=A6)xcA0<%IoHLV2X6j{D^6y6;M!Z&j0G>%EQXTs>8OM-8Xv#l0bi8kL`Bb zEv{QVw+Dm-0n$)UJ)nG6c|v(s@~Pufk6_%h*?X<(THCdb!w!MPq4tCvP7i%Xdq#i8 zOf_rs`n*@O#!loC_S;k@x&#{1wB#Xp*RODU5=Uzy*hFDji1o%uE6%!E>d|p z`Z4{u{sTRu4@4Wz*C2s=QpAI$aHAW08YkExqy@yrC8RhphbteUfWAcW08UVVFAGvx zqC8ZLg1W-B8X+`0GyoFo7gUx7;bb}%N4P;bX-Qo%+}vHJMn`5tgIZ&oe|u$BbyL?I zr&C{<_ID}a^zZc8HrxCjlL3y5Y2PcK-X0qmb5h_y*TgHFf#>AI}a@ROZgktN>}Muy04)Q zNPkE@?iM;-QCG8Tp=;PV?7Gw_92Z|~+#|l+cqe&Ce5dq?{IL44^|0e5@;T$jY>k5Ow?#_hH&`{U2j6IPcyU1dtQXg|E7 zC+$wU(%YVx+!3$_JsE20{-^jptHqOXtwVKh$Htu*I8VeCZP1a=hE}p4hQtXWt-pfUqP4hXhF25|dE20Cs>D3WWsHQYaTfX_8W!6evlc6hqq5 zmeS_JrIfaS<^MY~vXgZC@AE%@oH(*|B+WVVo$q|>`$|W0#&SN*`9dN{8b%Bx$NHrP z=5RSd)2vvh7K?SjLzb^*WY5TK$ui#df6jbsTU~8ovZU&r%zb70 zgwv~g{6}|oG@C;11a<9&*A1V?R(nZ8pykiS?f8G_QDtuE@YtLl%S;+UqPaP--m(%2rauy%L+WcY&qchjQ9{viQ|Ls9JDq-&=qpv z$Dm&d66CN#@E7L^u`LCXfbTbV%R&F)!x8?2qr-;ntn8}5(~#7I6*<~}>w%WF?auq0 zrO{|9{P(NZG>WAGsD=;T7{BxW{)oH$c(4vB>Ut^n`k(%3nZQs{TE-gObZ@}>C-i4g zzO1jbGGA2>v3x`@nQi3rOh3UAwcjHG1>TecXTEikRGxwsh65?!Wer284iJMCc`BCj zx~A?R71?qCKmiyKn0q+UQ~3iIM8ei2J^cXlsgq=4zfz0Zi#zPt>>5=oa2#gzLU#wVzl8o=wV;mG)x9CfwSIB9vW7JzmHXnFXpMQ(+-MjHU|4p#E`wDdALvmKVI3U?%|v7OdnD z2nLo4P8~p?h1UyMAwZ+09BDXil#ah0U_y21xi52KA`YP&M z(CyuoEX$)*B<_Kz$d0 zt%#xUF!&dgdU0nISCxPurv(#)`GAASPmhhN}i7_7ACU-RbtYu-bb6MrULNelEhg`fyK1bzk) zO8e8H4u3~z#6J=m_m77T`45Gp_#HqX1~O~84&)?pdvd6<6cy%|BnTPZFA*i0OV&ch z8~75)v~AcnX`^f-?08^LU@~wpAYcOuNC>ZS0QBDmnXIO^(hr_EX;OJvLWRau+f);( zDb*p>8>+J^C`hO|-;+E8u}ZwGKFIsPDKvcw;`a&g&#|D*!?%F5o(<@6ss}qHUTEC? zhu&l?VB8(}r(S08Zm5FWhF;pq=dr;AzKJ%xcQ@KGaE-Wfbm<@%hPH1ZG z?AfwvePm6W-W`AJ*0qt{-;BH3Tj(q5+-&!M??;_z71y?WMR1GPXlbdHiQmth&U~?T z$?|AXGn;g`t?DUC!F}MmenqdqeQ2FR6w3#U1Eg;tF+k#xLw*>`^;8IxFcxoOED1}{dqfGKiaCb;qmEJkq+`<0$Q^P& z@Z|Yvqs!;=0YXJ0B;ekHdk?N+R_KQJVEOkTK0(I_7NV>{G~u2IlEAqa^?7_zAghQn za<@E4PP!-I*KT7FXmNtW?%^OqfDwj`v2uJ>wSWypGuOjA)TNZgJfu1%ff%tUS=r}Z>4lnJ z>7F27x1cfNCb+syqXKvLn@deueqkTb)?R= zI9Tp)X`LKd{qJiDW{KjWqt|XVl{7`lk+;m>T5P*w%hUh5wqSLOqaEKZF1OA}Kx05JrOpc+#Fx&zuDCqwdR&0txtvAQVZ796;N* zMJ6I|Lz3BeP$THtveg zz!fvZ?YHvs0`?Ip2l7jwKB312!=rlP{A+ZOjXTER>*imRx`CH+7!I#V!&rRnoNUcr z2JinEvnD%MNW7gnH2X8q*-E)<%(cyR$VD4HKA7(~#Co&WG&U_oz zC6IK>3*@D~0$(YeHl<5RqsdqbQH#=qDN&j>4Vy+y5T-n(Fa;$7fMyXJNQKL*d6ACn?} z&)+W?GwPbVUwG878GOI+D7atniFn5XAjP)QiBftDzD<>$mjXQgD{i*@_}!%hw?1Z= zs~P5s|4W$D=K1v@;1%=&Zch9w-kIU%1SBZrSm1&=aj_C^PK&bADCXznPy6TQ#E-cV zu9hE@B3>j!SO#ItsDExw{3tvpJPPLY1A?$53lvpIUNu&=t!kp`P}Lh%jIj#&t46Cp z8*K#f+K8o+d!^vz`B(0q9VDPOQ(i8wBIQ-S@^tw`Rd!~eJ%Y1-`bOpeV5lUMW~WGK zlB-xfD|Au$Bi1qNC(^T4+Fb~olq{o`s)W9yC%FEx6UVj!h(`edgh92M88UcUuF4bq6R=U76uBQoOP7+;oA;VGM%||E=6zDuQyP`7jM(>C zOCnbXcReA#)Wa?(YeA_IW;DdyWHa!d5JQ zky$&D;#;_|t%#ir^uYe(mv7j6@8a&YE7_9rzMfRW=uk_nnwfZWYWIraOIP0gjg`Zh zM|&&lLTtyf&5;;f;|~cF{UCD!vbAxj=<~=eMkrDP`YlC)+F#*eb4Y<9Sm5%IN=2+9 zhh&9eRv|;!=&i!>Gk{Opdi3;Zh%AHaa0)63eAD0?&A`8-*+)kUcu)jEK8`DgqMT;t zux7AP2q9It6WqFUmI*|1(0nr0jyr)=xrn}dN9KoUu!sJ6XZ>e~Nk&v>4U-#|7@8AC zn=7xVOM^n#)jew z{JWzNX$1oiqST7hoXyAOtidLPzZFo9{X5+Kssa!auAC)%=w(ekoUY)+9m@{57+6#w zuqg~ipdy=(P2d|~&SI`{UI*vW!C20L*M8hc-u@uUKXBs#)*dvJH7CY?xMl#|)d_&1 z7;hZ@OJ7^%(l14dk;fxSm8@Yv)0%l|S?1$qjZfxUL*=!)K&+|#&VXIjL~TYzdZc{r zXA64num$4%mZE!Z{Fz20m15EpsW|gR@3rg6tLqEaHH?I7KfbajY&8T^zD1iCeMt{F zz%~bo-2@SUR%R_^78;19$*L)wf-^}=LVhVg<9kM=!u*1Gf-o!y*X87SyiiG%$1;*e z8|jJ$SW}GE=Zf{3S~jX-qhyof3|Dt~3L@Jl6F=*Zj-T_$5`2E~7A{xMcOMIoM++ zzE66|2I>gZoAe~B%G9XIA~seZvK090>^`=mWCYSQR7nBrkmo>6ty0dy&N&03 ze+oPyAdmpxniKo?aMIZa_X-*lz&V0@1z~0EWpW~{0%sc@;Clnb$@s2-mX9j)q5wW| zepF&EBm)~E3-crJE*yv%%k3=F($s2PT%$E+1eq^(JvOmCujaR^Ts8W0b8!-ztJRm=2yX=1p3-8&r4iB@wc5l4QkYY z*8XH^W@lz(=JQu8%k7f9!M&d{SKoBzt7o6;TQ01yC*fXsXO~l(7z=cRU7D;87cVI8 zEgtdFaVxzZ>j`Opvk5sYdWioRH}DNhNwLfx(ysTPy5rAYPAVCT=aZhidmf%=Xb!*X}G z)!FV^+n(5zs1qzda^%g=sy?s2&$koMKV&zLhfjr_`yFWU(VO|7=bw7Y z3#4{UMoZ6;%VX`afG578v2pDhNC++_UI)0ZVK`q6U?H>-&n2%Itr)EwtsPGtED;zh zDl1(jR+pVFk%sA*bU-Q?Gosqcl&cFz2rFx=Tq%b!znTsbRjA6iVBCQm)kGs|lvc}$ zVe7b+Ox0FWgv-^QwvPMv_(^|9>qzTZE7dBhPQx0jh-$s3eGXgyTvllV91ye$V}Zm9 z1Y$tAC-&4dWEs!kFd>eOw0m&u7=GZoi@4)4dyWGVyaU>`5r<`;#g+n%j@ydD4i7F* z#2s4~sCS%}yKuRWL_fgM1p6Y_}gy*lHknukG=Ws z-utb)$__b;l!7NJ6eYp>fUS9fySdRNDORQI5prQckG#e7{J=w0>+i3=Kse0SrE!(YUNI)E^d!TO?_R4hTEFT?IH>K z>r-TYq3`BjV{G98;?IK5m>#IWC<4@umC2Z{pjtRC+9R42Q6gWpx7zNCR~J`Dh-y@= zApAg`L_*_hA}OuL$QtTGb9I2OF7za_-S8IzH*!7koL>m$2*zxLH3!rxkZ2nSG@vj- zfiDOr9EW&a;iwbP(9OaZdt#*k%ZBwe&Y1AQH@t|js?^h&w_f_ez8y$0ePGYfnm;4+ zw-3DbZsx-o7y1+hFB=%DsiH%P;k0b2u+{G(slLTGJ+N_2kty6J!RK2W z)y}*L6sY+b| z1E{dbVsJU2TZ9R#)g7Hp743#3W9o!EK(u>0s(8CJt5F~`1$n8H(Ef>~9lr7SCR{lk zE~o=v9ovP#RK@G-3zAh(dVpi1oGQVoDp+i|J98a1K!*l`jDlviIS z{rit?6Lz$q-ETQVcep2>sWfES4ws6_w zNEdn~^J($UI}>ZGe*f%Xx0c+U%Lu5JIz}X@UVCk+@fxks-S}S*FG=LKG~*NZH2pAn zFLOPxbF?JA&B6g8855we8VS@n3NFN|RtTsZ31n*2iW~t=VXlr`%A*~D9vuj*PUE;L z4y!_v54bu&U*HAf>pJne;I)87z>5KPzaLtTJd0{O^@TQQU8t$6Dxx0-$`@nFroIXl z#+GIKmjrbnThsIu^}1jMA%>IKoXnFX6hwki@6IK6i#!D*V1)u$Fd)N%w{Z%er&-G! zjsXshYA!sDT6dJXtXo>hgr$Cu+hi-#2?p01igc@sSy93;s3~wRP)lJAmJ{9782u^) zRGX3xVuwJ#qafe7qhNRShC%hp1B?Ar!{J>c4usDtOsNGXEI8?TJ z-$4Kob_DK6fsnVd+dtkQAKm>YM=zK;`lhD3lJzwt z8qy8J4WkW$29Zc8?rl@ZWeg>3k(35gZl`Bi+Rb)$r-_zulx=D0TbL?e2qIK0@${uH zKKMBvB1|fQ5iOwJ5nD@K&K~1gKn>KXIp^Z^G-QIfR&5x;|HVD980TWA0P=oEchdM9 z{wLs24=|=GAt>_6COFUN zZR@_3`E=pq*O+~-qzXkpM2he3ve-CaM8sT|s&GqHFWj0%RQy4(EVdXB6?07b?Et8# zYFDp&e8;<)>4Cn?U4OYXPcV2HIYlXSS7p9<-dpL?8_?H)YBKQ41k_ELV#b=11jblQ zxNrNcL|s|dqf~o#Z}_#PNGM&ME=A_Xd)f7;l-E465?8T>8_w2X8I);is*w$Wii-OKod&+r2=Jc z6lpd&;iU9mK9%_*^U;oHzIYb}v@Cxrk0q9_U1#){Hh{LCoPFZnIlqh9_y8UQ>fvex2)1Ma| zGn)%yAnlqBOmKtUQ_;?Y1A|d8lXXktZP;(d;?BFvbM#wUtU9yd5+^UOoEpUq@Z3R! zZ2(vXu(G(AaaLNX=l9&d$Yxr;VsWkR$-b7JYwjIdzIbr|*5O-3ZH_Fa zR8?y_+sd5y-1pCJ<9NABfqAdtyJe}c-1Gt}fY6Z~6(oUGs5q6Qs>%-%_?I~lKq^S) z6gyME(3L_eT;3dq$;K7HhI;HAlxTsp0IDJnN@E4nhMOg5O$-Rc=}wRYr-QeAG+B}^ zIAn1%A?#Tz#vIhBAxF(Ica=+lxr<~}t!ad=4DSzWx+9wa;NKp}GIu=)?OFEnN6b6S zHJLAKNB0k+u{km?w|$FY$-ott3kQ=5MtJul0lTsZb9sIJq$p}1BE<^_b7AhP*=^)! z9ICySXis|n5!c@C+GHr@!R18N-xt zJcKv#&i8+*`0mN`^ZmEr_qRA(qq=l+=B?(@{T;~iAF%MhUKz8-6e4=zAfV8bgq52c zMxh5EC0X(h(DNqiCY@7a!?5#3iV_b@uBg~<^OUUOrxtIUo0x(lm*eL)H#Ka_!o;xI zdJ$j)^^dax^!ZORU;h*O{L+7z)4v9z|N4~+=7aHreoEgdc!ua89!jpu_gL8+_GLgC zUy@8G z&Nh>gr(zCM^HcRg8BwoiO-fc~ipgs0t7BeP5d)^27+c>7T{+nEhtmfv1E{T5fLW>d z5dHxGma>8?eoCAI#M+}!=>Nq=C`_#KVW&3iaAw`rd~$AQLk}_MQ*qKShpv8X?qf>| zS21UGAm+7$J%jg(qY5uBw^@P#GEtN;ztrBtCT7Cs5`DKTl-jcW4nwFQXbG?0KHA-F z-DP$(mbL;OfVC`Dek`Y}n`vYpN95YPDoHz8Wpk}ii(1+l^h}d*Ye;X7xH8xz) z5=)duYn3(K<@Pg`s5oxCX|l~9HFtNFRSXCe1xwq|EsuDb3o<`Ugq-=m_^@)Yh+j#Y#O~)Nw8Lrvn^ZGG6R0e`Ox{vximS}h`f@6!wqahlJ8T%`W}NfVOxgR z5a^O?7i`;B@s0JdcC_HyE!}~Ly}0=K$G$s!`PsY2F8#)Cw0hyr6DQb*N}UbE=suLQ zzSirou?2SlwCbzxeDc6c*Ije(>B)QGZk1(zEI1_i8Bs-SOE%<4r6S83lUr(2LX{G# z@r!&?4jNzN^Sez_CAeZ#Wq}^}{A^N_KM;;q`h9MjQYsRv*#ykep!QT(ft8LqJ+jlo zaY`W5ICX}DE;&_*!(=!-#u)>+920ykF3tc`$9f%~_arpDo>zt#S^!(im~=w`w-{oa z+zrQB5&ju?nGMM_T}pTL%3HQwGgV!m*#Di1qPV~2G4kQZ+|lnhXQrDokA8Q>decg4 z<*r*k{_9K{vF$h`^1T^P=A+zdSIN44ClBw5UAgv-huZD-N|P?PvSdvjI=ue-MGGy? zpnK$4=6QvbE%mTwEaPi4e`MZcOhgip&JBdxt4qb~k{Aiy5=u3ojT!Y&J_-MHsespa z@*L0~1-3%6$5)`3o(Tl6g$G<40~BW+gK2}E1NRmtmA$(p1hg!2(w?uv{*xx3yX_7P zR{@|OfI*v$ZP7siw=9e}SEH=(^hs4}nKa*aa^`axoMZ?I)h(V1Qp6}^6CQRdFD7kA zz*A9E%I*-fOl98LJM-*5C|UAEhxW1i$mYGs{cRdNzHfg0*YbrU?se(_sP(4a za*8@cvYs`h48E_xv$q4O!u2ny%~jpFgsO{lxiCbbkdZNN{Y0Nlt-Q# zhT)2o(dYvmK^ZYxrb#!V8`B-qy{r@JG?E;N&sT(sbO}X5o*)tq2D0bCrv`0;AAX2{ zi-lw3J^8-p#5u)j54cxQzW`n)bU<)XCSDP!>{%Z@49S?RZZKof;M4$MoEKCn#cb)4 z&TXn>=CuS}C~I?73@qAE=!mNqA#n$~sl#-=d3lS2N@teuU6$vuSeIO$UV9(I+&pFk|FgXcKP@I0Q6m zCAG99$H8_zeE+7+%U9IKdIbk8?MT@(usq@Rbe1hyA|sbZGC}s#l3i;rz4x+>J!LKc zSD-9$K6$>iQmXmS!FfG_}?H>u4LFV0n01JFY;Tr-i! z3Oz;XtOB09W-gY%1>@$nAAzsLJ`Zt#19Q~STc@79Y8@(=y!M9cGOOBlZtWXNR8%Gf zbsv7XYxC}X2)5g{EoC>?EZjcWwLDaY3xc5U;R@lUz#CIVT%Alegi)#-EiOa-ZnQv+ zs9S-5NDEOK(ht014(P2=CdP!@gk)Mc40vO)V3ZP9TZ#bL9I$&kgd@V2g>MMYf`AZ` zYF`v8?J*}cRGEB!5~^Dj@1K|fK*J&Y|9dBghH-Tde1kvvoaq&@Lq{!#u!#i<-o(V~ z8Z1xzd6GbYf;?Y>!lP~p=>zU)M=f$q#8CyZpdM7RWyN66^Qh*jXbJoKm~o52@3b$! z?QnD3cV<7Hjb1CT7xicM+!ilsQRkV_$TP2@rcd8LGy&CBpPfDVuBD@-GEWdL4}`CI z6cOkrPj+;E>)FqroXq@GR^`);Dr&&DO3l75M1b_b5S0)ues_E#bySi9Kyo}^wmTnrD7UVl7Poi9T2vYwtRuv7>&246j4*u53M!%`R!?=!t3`Y zy}0I1;7zf{3o$j@FHB`~HEh$+X$FFep=Lzhmad8Kzpykdj?5*KJ_{^d( zJOeJOojaO2=j;O4O(=kaDjET0#GP9(4CD(BhKl!WJ`M(8h6aTo=PzkwdvZnJ%=VJT z*7z@Ox#{r1bE|JP3E34(R!ptkxyg4RvwiIS&P8iG%+~0C-Mj0f^#TFi8P>{7^{Uu| zmtE4g_}bJ)ua;Vxx$(xXo{q0iyNsrNdw%)H#~&@1tm^WYh3oHF)opJ5-lKXG07G1n zPHt5D-Gy?h$|}5R{J?dq)(3;vl|X$q#EYP2g8>$15ut>>%yhCmgosjF<+4a}3Ta!u zj5SegKePu(pz+_%m>8Fk_2#kKj-s)mZABA+iot@>28sZ4t>X4o44#7{toR?U!{*im z>MJAIcEx!e%EIxx;FBNQZ~5mVh+J19EEudYIh$Eu+lPA(1sUCS$Piq#ud{Z4AwVH? z=13a^xJ~i?Wr~6P0^35`RD;_U-+K5eHC0XCm8nR!_U_)E`Sfr49dj6uNBTNyCDmE3u|Nh=42 zE4_{}hy;}TQY(eg+ms?uj%9P~R&$C52&(h=1_`Y8AyEj9Ajfrv#R7`b=fh4}DIstG z5t_ABb7F&kCb$0+wN>W1B`hkBpQpB>o2uP)E5CQ1+G+u+z|>a1T;N7qD?J>uRT=ca zk;K)rFQHaoHpzvYM>tuKBT!zWqhtn{f>th&Y(fN}o!4YT7hIg2x9K3MI(_CG$3ha# zgFG8&yMXx(o%?)fB5TQP?(e7R{(iE;?sPjUY)-c`pI$UD;Ck3~$IOd&^fO*tI8^So zg+jP$)ldA5+DHD1C?qP9g}MS^PPJUAp^D&IbOPZGM1fA?(WmF)`*6Y>Z&%MnIx7b!rU@Wka;Xfd0& zNZ|8%I1Jjr>E8l!)8=zp~2lIwi)vzH0_3qETBEE z^hFSLd~iI`2Hqfa?sNKr140A&p7Zm-Q{kNzxJcf(hn)amELfKyeM?tsmAgS_4qRPR zTyFLhCD>oHYhu<8P$}c;m_g&T8kh9@wt98x_8e!SBH+gRP6#8=vZM8f?L4S`v2$oEW z@FlgP2@TQ^I)U6$SspF1ILpf-|kHxEI zxN3f4s`Ddwa~!)Tcy{w6$WT|^n(8`dQ>87?nqIqhVIUP!cdse(S|Z{=_cD2RYAye4 zIm$jAR(H)mO&?5+*E7_|KHJu%D;nI38^7!KTa}uzmPHvVHQpdN|4hSSzu%(5&)^-r zZ1y>(h8c(avWM7_EUC33Qf;wWNGFBbEJKz{EtKDxbapr?BNX*ECM>Amf@~IKF=D^F z1pICz6lOLWO`@`;PSgSJIfm~b^Gl6D5?+d5Pa0t~RD}U31JrZRoJ5cS!KMbdb0<9> zcm$ar57-+x0R)x@UP&I=4;y!|La-G%kZiSBv^>loWae<8Jue%6kkAsM+t=17~l@~Q2yK49N3Bf;n{y1sQZfT z8Ugl7eUa;i6+n#sPmZHvPahRnd$j> zdmE@QoHFF_wxBMGQ%ZJA6@v4t7^wyGkLdOGVv7RhEL=A8{?er*GhZ!Ty0lWMvC7LO z4XqPYb4@e+l{7<2i*3dg)Epb3s0r#tZD8~Zi4-YDC!k_C4NVm!>?poScy8pQ!qf93 z-+?T{kBB0ubq^Y$6m}S1ARvN@AVz6BUpvcp4!jMo;yVZ4K`Wu^AJ^xaj3ysc5l@PKQ3VkZ`K6Kiq!a^8NDQel>o)6z zb;?Rx^{KQS+3ji%k*fEkqM}sw81$x3M5m&MqAy38XtktYt5COfr`4&>dUB)_b&|v8 z;owN`Snsx80T_z3PU@iDQbBLfYm>%L2B?1=JGsB+#Ng_{doS ztw7JdTvl4S_>)XPWXiv>`paryMO)vuB=c(Kv%$6M^_l;EbdI57@{K6FZ_8g z=0`JJOhi#B@K>2bs@pzu12e{eRPEWb;XPnWldcA~v`FG7ci(fK&0@iVD(lsTno4~g zW(A@!ItWBDG!R)V1J7tISxp#Nso$CJQ9C)0$m7gc(|&`yI@cd9kBSWd#HWMmLGIT| zpD$jetb+Yv4uSt0ugV%Jb7m>$^kidnaL8lyA^f{dxGhJ2J14(!TwlcL0Xn%uwzJ zVA1pVBKMx+;YHp#%hvDa0PP-~$FoaxWNzHMDD&TF2WQK3s3TxSmXanaPW}~)nzE#Z zisne8#A1aa2Ny3eDvvgO5vDTXgNV!wXTjk54Qyw_OtCcK|G-E?x3kkx56gO@)9ejv zfpdy|g#2qB5X7+xIbzG&ZSaXH(#(8^{1bd)MN*%;MoiHP0imWR#Y9vg#-A%vdbCX! zG2MdAiW7fF^MbIvm|F}%uqqnO=L{zJ_^kPgc5X(0*!=OyibYT9x9E?5{n7DNBX07K zGDd_Jk1~SgLl7w^i3Ylcyq`&PHD*^oO+cZxCfQveB*$~crQ?Mdf$fbVMhXtsFgZ$& zlY7WX@*v5OIrMB1`T!zt@;vlO-fSK@oHv>`p0_7&GVdUOG70kvF+KMf&~r~{rZkMk zh|m44fJku}v>k7JpL+<8AVojJ0l{ME0T2x?Hp}2WnYD6_q?#cUDa|_8*^pOR7R}rn zFUSQ#C1+9-EUTbvQmC)U8E8IoyTK8nVy3-!X&k}YXAU^R*t%Im{f>N_DTTQe6Jv+9 z&}@Te*CHgxlw)dgj2aV=YMrv9Xe8@&PH~Woq9PsDAsdm6$+pQRWK*(3vX^BdnZPd| z7LSU@#d`qr^q}~N_;qoP*oYGgP+L1R{XYH<6&+X);VdOqG#~;hm=jcigUxEb_(#&< ziY(P8ofVb&GI3_n1wT-~3%bTov@Ya$Z{dpG3m=2Dw9(*tFhPj8jXe*?g(kU>A;(2< zQKCI!prRMcNh9ea6J(kc93fvPKOjFLXGy`ux2}U8p~vWLK&&%GGjf`Tr%VI&x?Eup>fyfxR>QSbz_n=^ zKg7d9n+sepj0bM_6yX0UxV()ox7-!i1#0!vTz5;M1%%JZY zk~ZlYQDL=#$fpt_b#<=2+GDA6nd*v)yqHKDsKmYVej(1NaIsZTVjP3_shRjuU{L1v z7~IOa4LX!{>?ik!3)ON)_u9TKP)W3K@6|&ny z_#gS6V2M2{k_{#lLYV;F(+_{Xp0bC-c3YT}-#Fkw+{G-1Y`BdGCW}RsRt){$DFu@% zQot7wUTCS5*bW#@DXs6^(DXS@4|A>+7bUTScL-4;A<|;fD6SHiz&9~UV7bI$O4x7Y z*Qd9(9y&U@G;`t?)c&%&Gp`JWytd4vpLlbT?f0PyvoW@CY3FM@e}*E57e9uW{W~-C zi#gp?t6KT2?&SuVNP=kj@J zIXr;oL~q)a_MY#|;!yF093ngbb(5#|7mQ~r1Egya0{b~rl0jf9`-^A&n z2+#wc4;VrABkO67yQ-{jzP@?Mj^jVyxB!yZiQK~KR(0mYp$8K0eQ%vPQth_c-um6n zg`0uyH-BSaFy_+febsHc%r$TCulo9DeR}Yp-oHd!6fRzs2R zuyNE#8VSIN-R7p;)@VS|J5D279PMm_&@R-5LSz@d!4^JudS-g)<(Zek?>aVf^1Ty7 zfV`=gepzw)^vp>hu7T5;@96YEUgQGTmEuxEjMWS!P+6I_gShb4JtyT@r{QBg%>AEr z-}!S7782J}b0S86pyOL>HR)HMMMrQu#mt}W3|fZE(mc3@rREz;ItmxXT<*AIOZw7V zetZ4Z@}NsM*st9xD|n8y2UZrG{uo_061P?~XmbP#+;m%)E6u!s0+6x3q?*Q!74&0m zeE~%)bj*2dW1iT36Q3Z8>TguiWN!~0ax~`Aq*xWaJP0egj(CN9jq~dgN$Wq>Velmw z3f#9;2#UcF%La^2@}h%dkGLZs8+d~S;kWzwTw^rC>j2no*U!6YJ68TL-82yU3$D+T zR1yk7zDQ7ruSZdM{&G(9nO}^hejEps;jsCS4i-9mfrB;FvS4U*ep*qq&ZGh8vw;q%HfbUNLwN)csl57hUf^? zC@9WAQ9krb&Ebz?)BweAKTMq4dKxhGptgZ)Yv7C}UUyy$MG7z@7J(3_Hs>QH{{rb3 z%toOND`%4Kycn=lC~2wAoc!15zuN&G7_C`$@ZaE>4qW;iS@0iGfdM>Nw*kYQ!dPJFsorrZ?G)e`lVU?^U1$7_i z_ys!kTg4ZE$O1oLR2DAojS&aIse#49*i>+zp?n_iJU%D}=r`bAU$i>e@+XXB8;#f_ zc*|lM+4EqSDmu?6$oyfTS}DNj$Pc#NOU;2J3wU&7wSM(2XoW5mQ!N+sc$oshw*<>l z??kppSF93HlIq}vV99U)frCm$l8;8V%MeXt9L)#MV{4*bygo7LbG#k;9FxTIWFSXY zsFA_!kp)T`*vfE8nWd~e&&!6?Y_5itSy)tTah5UFR<;a~&cZU#{2)L_j~)k+Imy+{ z@}3=Fed44zRLtO-7^n(^4iI2ZgjM=qG(mD+8|W(^n&aF9%Q-7$L3BoW3vP}qF+y`B zaKM&E1-LoV=8j$yxcLd?8!HB*CBc>V;B>ydxUWSnaYw!+??tB&qw4ZhN=TH$bxVFG zP{m6+3v%d;M=W0CsSpTej$wBI8Y>l4mHTq+)$buY&`zomS|;;g%RLEe)j3;@?jp{D z)v8O%2u3b@UG{;Dl94$I2n0hLfbS$exUj~ZSHw>Y^!3MVY<;6Z{K}G=@f#vGTUVbG zR-VM~M*f|9H{exI>g9w6-cerky6p9$4`d${F{CUfuZSo>1=yB7I{iLW$$(!o4F>E# ze1`eoek9WT>yN+aN`%C|*GV3^u${1*rg~Tf23Sw_^B!9b!7$GLWbW>~>k*k}x zkEAL$Y}mf2vU7W-L9$3vDcQ7fd&dg2V*PgGAoNLY?`S{`?b{QhCF3P~DkdxF5`Try zyvIzMY5jJebQEyZC#AGhz1;*>E=g|!*8>_&!8si|3Gv!#{Fwg@Mwx=`rNAZp)9@{U zpTd?qXC!gw7uGx!$VE1^1;tVn)>aVWQUbN@`8qo}oaL}DvFF0y8LmQj{*_!j?Be%5 z|F-;-FWlPMx^mfyJ9@iU3|?F2Dy>O|JmF@eCB&3pa-$99>gD<>xCcs`r{VZnV|_9C z&dmcuJ^gpwylU*|{wB9=;lhq|GD5xpzwPedy9<7MU$fh`i2E&_w{-FC%NF&G4DP$8 zr5-(9Z1Qw;YK#0m-CvsgmR!{>Z=;+Za#4*TS{t;e4OPn?$}G&d+U^QVx_WlqxomY? z?+y2!K);CwT2pny!*QD-W9sVN`HiL7Cq887o-ocwv`XgVRBxjcngBaak_aJV2z7+U zL)nID+%L`JWMI4!9w*~%;s6;XY{?>dr>Qg9Inp`Sxvle1=gXaMbe`?}v{Nz#Kb%K@ z;G<{p`OmtYyd1s2b(2>bE7O(3mE)C@l?+kht33Z2?h}Rg&wt`>;w1p&%}wScni9Pu zO(VTHcs74!&(4oaq0M9kAb6M>P!=VEW5*UPgb~ofj(g~d_W;2I_xjf+AO=CnYmM;V zaP4F*hAiOUm46M!%-~=1_UxzV_qgwVfpNiHk2*I-7@Hrnn;_wRIZN2rfGyz)s5Rj& zVYp8I9XHO8P7zO|&jGDMI$4M0b;i1M-EbXXU!2Dg5v5=(9}T=6wAL#GMptkdp{ak^ zH3{%#7mOU7ANe-A2}WXc60gxq`n(D6`4#12jH2%Ou_^Kf?t0~NpAi5H(!OEesBh9I zksPEWc{#b@VD1#|#_87_);mhJD-v0Po<#pD;`QRmGm zOycn!;qw>+{OASqqf>yF@+uegv>L5x>#+5RRd5i#W#<4|7bC9U3iXHiL}N0*ND7pI z!|4ZN-j{VW2IHL4Q5s4PrJz#Q2wPkljy1o;ndObe+{Az*Ypa#oBA7bA5_+^OxE?%D`^rqeSifqDZXVJ z=ynBEe~=^O7`cs{Ag9Pfx_E1fhzdjcrg;SBQ)3 zFseEnihKly3)s!|D**#gJ1_wCP8LS(zyS0(W&kp7G{97^h4B7 z1xZ2;r*ICVCgoDCC{Lp}GkqMYucxs=i?0Z-hr1d%t{daC#^?d(q|^P7tG#AyzyIa( zMsI;2nM1e4Wdf!(r~tMd+&i_OwlZOmwM5cBfYzaLL@8;aUy7-)#=ucmZ%}yT1;zp& zppwu9BV5#R2zM?Gah5-<3S?p6^M{a$vjSlLS#OL>r$ZrB9N9g2QIn4(rH^boynFqI z=9W}KP(GC?G3MUW8XH-5drM1u6eHQ9I6X=F1=m7W1j_KmS3qx^N48~-NeSNoEXi~0 z3nmBYud|!h+st<3dOBmP95LF9i6Qx0&}L{!;|GmBPY)UB67(FCuU~0KGw* znnXlxm@n_-N*MUrB-)@~7k>)eJ)AePTDS@-&cNZ0QQWymcJ;YZk+SMv&?p|y z{Lkv;2e$SvJ$!iAz21gbMchdX1nr^o{svq&3E2Ik?n1Gb{hbnXDM+x)CD+_ z%KRK@KPA-2w-Xwj#-ranH%q9dz|Iu6sDimVE|@BZw!_CFalC|DdI6eFJ-eW$@#+ni zT>zOA54iH=vDV>bV0ZnTo}|9VR6_NOg(y$zRfI&M*Ne52hJ%J9hSv=r7z73?*JB;o z$Suco+o_>bV0S4XqKs`XkSt!r=lmXw(2Rd|{%2Be@Tr}B{q{nW!MExDLbSn9YX8Ps zyP?du?-HicYtR+=x_V0CNBdRx>Y;$rXxzQrZ!qh2ug2?Al6eezvL1&zH#cOE`e~6? zFP7-k#0Hg0?J2sOUm3pQ5Im8S&~=ItxcCr2*6!ro|GA(SIs!N)D;u?WM$Z*pi$W?`pF-J$9+zm@wz}b*||8rq@`Cy9ZGbeGl~mW-*}!e;_dqTSBVIeJr0qwYgG) z5^Gc);t?@Ph!tX!*e^~3r`d>DD87YKt5t*shR})v5GsIw&cBRbzqSivJ8;ne9tOb; zP->8cz?x&uR3^aQCqWm(o`pTK^t}R|!CRR5jmKyWZ0hzKodsq=`k2~hFz7O$+pBL{ z?KYIUqHw*lJQz&4qmco2l$e15g96t&i?tt5ZG5NVK$cdkXFbxih7o3EPgtCo%O%R%S=goS4 zfw>lbxM=X{_{FB?MxeApDng3iqX+WjZZb zHRQ*cr*G+re06-eb2=lc=lMAxp~7D| z>VnvB*RW8$+U1CZSM&%dz>5tF!WOF|PCk)oOG@X z@u)>UKY&P6KB#EHX3id8)?xvD*f4tv{gIgjeP|&3-_{DYdu;utPveV{{?-f_ON`Uv|zH$Eq5q!JT}m z4qu;vl_gKZ0=gU6z&TcM2B`wtxsbRO*V}``#8n13$g4U=)n;6oWpV>#vZ3{n(Ur z8MPX7S*|!Qfcp_?)-I_iQxj}iW7%pWmFL!*!vyOVvF4cK{TZlQ!Ak(vk`FVuox`o* zxWSYw-^^-6m=v7AD(w7$i0AWSE++}R4E!zz)5HNi8Cf$0UBbrOCX)V&@R~mkFRqN* zs`fpVbcc&;HY3Sg3&!bi<)$IMBkC(etJ~|FZ(s9p#Q~Xlh@5B%x@_!Ii^FcK*3M?O zWd6waW1O10$Gvf|Arg0%nUx^@Ts&R$AjmWyPrn_lBa1<%(`B4Y!utS!IFKW|R@AfHeXU4@9LPvyS6<&_2y`C_r$E6I2`(=FV-W zCflTp=bR;0$b+)*D0YeQNsdzH)rF5;e%;lh+a?~p>%bfT_1K^6OUaPa6;i56sirMW z-!b!SUhk3z#yXo{(};vCc6{`=eLEDHBd%!Fg&h09$u@7jWqDZ}LR*V)bYl!NL`_9CeGmq~TMc4GM~^`Ua&9u8^HP1D z4#G)dB5_z!fImIRQ>|fJn_HJW{@y~efRBujOkaJVku4nT)R#%9vd+9}k14apSmF}X z5_HT{SD_Zy#!95MGe1TonNw!+l^ILnu!pPK3Rm?Ga|*I{p`^)RC#IyjDZ6y6WUBN~ zDW#nfxy<7bCYmA+0X9mW4@&Q*k78~M%tWHVM-SiT333KkGIw@@WWwX~4#NE5N;-Rb z%-0)@?#$AIuqS`7=Fex1YUT|KyV$piKFtHx*(NvgfZK{~%EaKn-t>zj)k z-R*9-aU@l>Z{Yg&lBPPi?gy!b)M4hEL<#I7<3aTc>hBg%vZ*6r$QMnGLs<-C7Af-! zr`*aZg7lr>LbYg+AutLQW$8RXUbt~JhdOoN`^$d>c_~b=~gnitd)~TZZo&W};K$wR<39aj^DCt)RBMeQLl9;(?}gW|w)& z8*iDC4<&}uL*qjeLkEYLAxGbM7=;t{>3Xu>Kc?NLozPAdAJPi6dBq?-e#Z*`axA(~ z`UjQpn3Ce?5F`bL&hf&0CKG?}gyQ|o3D}2t75;Ccr4n#z#L78+c(p+6ftLaAhyU$e zKQEkK@kPQ}f!?Ut(2zcH>h-c`%UW8>o?SREALg4bmJd_edHFam(q-btnV(%K(wTR2 zkyuvMB9SmHEzH;L|13#uB_K(4@i|GN;odwxe{W)dDYHG%FW}fO*I?>`~>$1Fa;8AsI7S_9-dm@Z%ejyw2f#FwF%l_JMSr;EIwF#1SnLv zTQcZh%-<65s-bWS5S>8?an#ob{4mF%H1jX`rc56_iBtdouQw%%QxphV&alzqLmW6> zQ~-AjtBtG~$ozXv@lQA7P4dbvqZ^6oit(C!Ta0XJL75lRp48~3m;oJq`ONu zRWPL!yr@1>Ll#ZhbGbcUGt$x5knHn!C%Zekr@9Yy3%VK4h-WI&9T`a>jTxo-lT#fH z{(jWoH#r^SHayl1BcS7nfJiX8iKqm=269k516S4Z=Rv)X>5a? zR6raX?-MAN{om^g6cA|f>2>j@x#<3YEqCD!%GOx`mC1ipHJQ;@f!GCanU7w`ZW(-+ z3?*=v{JUzj_R`$B+tj)82}>OA(*I36&D@lWM55a4j`@c>#UTDx1zpY8zTqk{$~z%{ z!q*ybn4f&D!R=dk^ifmVMB?&B43fIXG-s7Vy%lkm>ZZO1PcD!wt|RL-b+)rMT1x0_ zw4%f!Qdks80?}nEV-W1$liaqz)*twioSNqC0DQP$gKs|Q#P^$KjlX#T$1y6he?e+M zt8+AU8EP9_b@e5&U>B*dG??QNf2FJL-S&lQo4Lf5SP+R=$?Jkm%c4-TcSCt;|I&uA zI~E(F^^pcc)MhGoC*B!K$<59xS9xV=DJ~WzM$t*~3-T(6+*p(H9A*cJk>Vw^M;80X zdNHm+4Qi0E#^h6_kM7Dm($kYh@pM1>Wo~8|LC_-nE7+1H@WDdjUE(E(1_Q3Cu?AR7YkHydq9({dNE-ZY?0ErODvof$c_-Nu*K+!};-i#Jd{C^HK3%5?AwaY2=H+o5x~YyxRkFzA=*$xCJi| z^~4X8*Dp6A!2;y2s;DB}epFbBG&YozkM0vbE+lUjqRm1CT-}R>$U&kKN3(<6oI;@# zdcFp2u0g>XbW;ghUxEhVy9*7vP?HOlxRBivw)9$7T4zWb*CeeBKGy85eds2%$h-_)w&~1@P^2V=#JK=`N8fL(1 zARbJv?X5zURj9%Npc&|KExK8Iua;b=-K-@SYf)T@f(jJRLDdz=9Y({#Q6Z_fX!3+a zFqPMob|3R)){2v~Ni`%es6jvC)^5Rv8UZQ`q=JSMC)I`*C5#LqjbZCCn z@5ub}LgK5ug%>ejQLD??i>R-@V4GUzmVGc*w)X-OELwFj3l`pg1G68|hq=6sgWG?% zqo-hh7?PSj{z?A_ek$!p$O?u50c{^vep_*9#2l|VrycA0*AYL5oe29j?Lo-lffsl@ zBGLJM$bU{T>_h%@&JsU|&tVQDYpmA;*TKKvVt5w6A4Eam-QZbKpw|Q580H#323+Ii z;Bj7>Ob*9UTO75A(O?)YV0&58X)2TjQa%wuSNDR!l2TTA2%pXQAX%gh6%K%%lhO(U zvffHmnUYH+u(^Qz`SeNd8$e{u96gqRn+^D}@1Hn&bS7~6#4-LXgd2_2PGA7V${BRB z6aI1CZ`eJ_k3_S63Aewn=>cKXAhZpt99B~v?pUCY?Xnxmh_kwQ;!$We-FE9|quy8y zIs|`VbbAYGT$64wscl>=@V93sNwW1&=FoSqdxHKnjWUvv%!}X6&2feY)+582zd!u6 z&gHsgL%;-a{+zwC6-(HeUB4EEsWVW|U*|3J{kibF?yKDALoS9NbJ3 zE3`D`q#*x<&gOp#Ei_X~q?Dw_HG4FZ8p@;@0ftkbK2>6Mg!K8kC_|J>g1$0I(8S20 zz9nPcw{!KMI$_KnA8JZDZq@mINjW7ZC^L{$)`n6ts~s)4^j zaZQuZ=cYE!rLFKXA}=YGtXeIQ8VvFdp!+JVi{JDOiqvpqUrN9TsPMD_A=oOpV@Z#H z^Ec6d|K`~n4+Gy<;MHK}@PyriZvXM2!Kf#5Q_kz}WLd#Lin5)}BtuMcr%SdA34VTz z`#F2A!OsA@4`=)|^QgchTuut1z6KgfVIAkHCM4h`OVb>nE5#799Kim-Ek>N(n$20j z4cDTbO~FuOV<^}}o(MKI1>qmwRXBT`=1w)f_u^et%AY!9K>&`ZK%k%iZw(k3oPCM< z3wNH?adQ7I;DJNdl*~=QxI`j1m)k-lu_N;sV-*|+`L88DNZ#J;Kov%`xEO8FqxA_i zltA$W8mU2{8nhyT+)^Z0U_Qf91ufb@1U!0OF_r(U5sd)5opB;jl@PDAqaHg-*-;30 zS4=2sl+r{(DW34uDR1Bzld1d^-5>FaYbF%l1WK5z_DFqMdPG{MD3+QPQiW7)2C!1N zPKa4yjwfg%1ydh*TNLLKxDgW+C}_{TiYgy&TLx-ztU6(s;t%i$RIK8?6X&=FE!;rC z*9*b`o{xh&mmG7Qd7MGSib(6bj9Ja$)A6KC=9UYktLN6c+VvL~O3jBi->e8}s;4 zRiULb{|wTiEgQzpW?sqcWbWzIdtySZiBCjO_g;_C-I>>npsj+L#{>pi4VGXHaaFRl znL#?n%~UXym_enL@k(-K97V&>?+Et>BBCR32lU2b^g;1#F+$jqZ9IMyZ2S{5#{i*jUTuwfz2`G8h=k4Sz>QT3948PM_$8EynIA6uc>PM$_WOmG>{0{Su~HlsDwtNJ zE6V0&W?nOCTa5dE_0dSmmR-MCK$5fehHDY=8Cq1vruCY(%>P{5SbBrfnoG6j%J@Y? zj|0wG-{tn1Z)Tpes$e&K|NoHoCh$#F`P+ETy;+*3OPZv6(POHMTxntsPE#rpjr08(^atoy#Zmb`QAa!s4jD_Yj1*@XGlag5CT}bbrZ`zO zN->Q>$HIoNzfu>@r_!<5$An=3VoZo0Yn}FY8+hgBP9v(i5#2d96@Dj7|lL1>`!LaTi6r$ooO2z$< z*)L^+(YufwB$*UpG~UB~L_vNaJWbM!A)w3tXOYp3%Anis{zRQKi!Aw>$5XeU_x4-F z!)kNE#US`YZP57O+)di)?JnJ1RfYK4oDq#iZ!j!zmHzdoUtcXK9)O>KlAuQC&aV}A zlmyM!sIqhgSFJgQqM*zb135XIq2#peTYe$eH;*K?KAK-tR!l6H+pn^pZA`?9X&iNq zxJ_P*3ZWqKA3GCsm&HiXPHcA4T}E8_vHZ?_eo2Uo8_8ho$ru-i5qpfx_K+428Hg>3 zaYGd(M_E|t2?huQDwW0eNuhw472;#43ppWsuj7&%0#C57tuqi*qhM z|FTd2t&m9kC#@k`_3D%F3^Yegj=*VaSLV!_*z!vv-~ZBSr9@mI%7}a;b8#jl98)dM zgoI=IM0N%FgxW^&K6WOgt|l}W)y_1CWI1uva>8FPrTIl>-+9@I+Qs~<^rwi-YR$`o za={pMM(1u$+khE*l4E4R`QRP04JYS7j?#fjZTN1$>x8C8q`%_}!MB_IJ93Ha1$G)q zP8mIo(tDrscPhLC)sA>S-hIm7smR@uwU<-G{*Lu8N~5Qo(v{E-B6mXy(9c}kT2>={ zX4aXT*`Elj&@r+nFbB0iBZPP&us>^C(a2%iZciK^~;04b0F*^#JBWMI8S}CB0j-*nG$F zN7C3R9qXw(W$cEjWAejn-BFamuHh)wonAvd;R;ciAWL-RMo(S?>uJocnL=ObHQ#`1 zfwcf^3@*5=QY)i_@hPO4>D5Xze=_xX(*7s}%uCkRCQXZx(wy}A>72O!Tazq*UnySxu8N>`{78ef)37!~v*(%Gh7l7EEWzic+Tr@3w7+jw5WckROr z5*qBN>;~y>b0njVBIN4ovhp#9bho8$F0`8yir%q$N3nVgO_$$J$F{c{?bBn~%qqH% zFf(@GaWIU~9f&#P3btdUIga?V&i8T91^m9pT7N(Pi zD=U+0#%5HUJ3Zq^vKNy3uiS@`K3_SlqM@;rr>4G@-=p{oYX2J&T3MwbJ7IISXD76V z_UvY+W_6hr?fGe8V~)ndqf<;;*hUp9ZBzwvEviS|ZlD?vBbG2TDl21|gT7>TAWgln z{)&*%F#Y^6WuPbJ_r%<7fA~%JAYYJ|wc6F7$!dyK&i4e`KmR>E48@?kHbX-$7he~T z@3mfOdpd@8PT4gFe7ACIZmo*x6$m$_*CC6+&O1Ik1(SJXmnY`iN=aD}$t@zCd89s% zxbsMB771jLj&u~pkPMDYILKBv*;-CoN|u&zffCYb7&mZcE%??P1wvY-dsSKas)TLA z#@TF!lCV6HV{eyN8p0X$nzguCW;~!h3AENBi4A#!xg<1`bTyMg6G;b2Bq5g3y|c;e zSyj$~Uc0f#Y^XLQ&>?nKxKp-Jo2<8%H+8qyr*YMtiB7Jwb9g~D9QB5QxV>GduN9nO zAJ;8#y+TQmkRu<}q+zYzo;*&?-xHI^@Pl{{Q&$2kAcqeeIz&z3?++vGaNy7ZSY3EH z9TbDYCt5|avH_;B^dB3DYJU8qATa8-;$I4<59L42#H@r*pP#2GTyyhdOBao3GE~aFv9ZZXO`7<|IZI|Lc%!&$Tb)nd@2*qWYuy8B8m>A@xZXv# z|M~W7{8fHAANI`3Rpn<5yZu=f6FL8a`-W$B+_}f}W~j334U(a`Z10%(t3)-71$ZLp zqoIVk|Qn2YzDvy2GLy=;qR|+);Gl`FDuV=ykDg>6KGG{5fz&Zgji3 zI*~Cif+&{1nsd3N8oAz#j(Hqe8X=t?VlF33`9l)<49PIh~S!6SG}NvW*1w|u0W zEB6|Rp#_9e!UXCeV=z}kIKny{VO6Z$;%Lp|s=^u60EJtISc&@tb{qU&)VLl*Knbo{ zPL#E+kjzhfco?E5E8?)}U~bZXEazBDk+O(2Icd`htJ0d64?pmK-cJA*6e4gX|T1{qF`nHSjeHP{Fvl^vxb@J8Gy^o<{{g?N?Ql#9_ zQc>Dsw|6NrNZYFAbh3b@c(f;N z5jvWuSBxtCrhIEJv_E%@mWKI{>Ype3#<-DgR9hJt%>HOHAZ46F<2Xw_J@2} zo(T+PHM)0Ytap+Q=R7AjS4%3Nnfff@)MT~W3&23L0z%$m6)Z|$g)o7}?lqO+bWM$% z6O4uSu#Vn#P(IxH^X`4^|N5}?nv&uHys z{9q||f^vJP%zB~2o|l&9EX)%hJB5gVpRM4oeFL;$5+6aDG7b61B3rjOe9HXceG4AYqClAbRkf zLr}|9)E*f==mt0FVVrtGRWWW61CL?zLMQWV7fY81AxZrw{_?XkgBkhj^2W<+m4?pi z<^|o>E38jgJHqx(OEv$KF)n-ZZ;!nS(QuPvGkJs0${KXlrkd^XtcAWi$PSb4*lN@oO&1iMbNSN~sy5FkhmGQkVj&?rg3=S_)sW)Cl zE_`{zimY3fj_#p zX&V2kxd?XN)UnBr74E5@!+L8%?_w3c%cdgm@?<8Sd3oSm8zIFO~L_NkmagP%n9 z3UA?;p;ogRy?*sZ^ZDg@3e`ecm5(pTY%h1XV8a|Zhy*i)9*qu5?PDaXjcp2csOhn0 z##^djfo>Qq1KT5biC^ZkcB%{Heb#RD$4FBR45+knpS4RpXZbx1!2*804a^i5XLn_r zY6Df9_PKK!a|Q!{=PA!xrQ!l9@Ib|`~PT3wXZ7*1*CS6yM zg|0O&uE#~L7#-|gPu6dm*)LquQ7fRsca=lPQ8mkQZks=R!v*8R3&*Yz#&5kzm^W|t zh{mNVDGTRzjc9Hi>~9n<;aQ4F6+C~_#!HmDg$ZiF;qni@{mw8p#(_GJ!+`Ql0`YmN zNI>tK~#IB9%o-X;QX6|DLRyP8>;c zR62#w8z66_3(HO-W}^vkl$h zyEZ(2;n}zRFA1qh{6%gwx7?y9M82Ay`ov}3*YCWeWMNtgj+ft+c<||c`+3`lI_4V6 z<~icAt}xes|0U3S^N?@ib?0UQ%lB`ot-Jc0J&`5MaK8+-lTr>JN67L0~nfM#&F*lx?1E1q*0@04sI&hBpV8lL)nsV~TWT7bVhthAi0vJR$qlynZ}5YfHIql(>kb@%+?#}jeZU7> zhH3&DO2dx9Kf39dj6)S;iYY$1zv+G&NP4fj^ z*PB{Pyq2J{X7zUG!u_F26MP)9^uWzKh87OYMLFWS@9RIh@enyUG_%TwKBnwM|M zH}J&`A)&p({_tMK7kMRhW4m&9iNC*1Jc!amuQgkD>4$_YI7F_wxTehiUDM5n`v!Mh zw|GVOAo=aOgSU{0dGpM!^=&o5LSxb7#+cm{^3AxE>LUZV)Dy}Th{V;%Iugzzp~5RG zu?RVt6KUIE7Ws0ry+T@gNlB%{8kTE(+3Cj0a2^#B-orjhoB$o7i$WgIr94tM`S#(u zqwrH`ERtHzl%r5uydW25Nse5tBG&+t8<@;kp`^#hHxNG28kzAOjN1NucVmNlHCNX3 z)}^!B#WTszbGvfwHLv9sd6uc>uO4Z$m40|Rahj?uT}HjnL!vhk&&HLz#E1VBOLLax ziszXl@{IvsTqL3AfH(Z5{5wOtfpiHgL?5p0 zO~t7wq9=oOd6p18?-`_dOKGICv!RHg4pQ^7yCu#05xNIR^CIG_p%LFmL_p?p9$PSvqQ$UU4>+6wP0)&ggR~_vMs_z0%4^# zU9Z%%R(OOmNQ21(+HX*BuZ0Xfcz}x4$u|Iw#IM5$1RbRL3O9~KDqlejOOBcbrvgiS zDeO*;7J`_6(M8f%dcPFx_im> z57k#>eK2qB-G2-w9y+*Vvrqi)-9m#aMh4#d+8yJbZ7dQ0_1G(xCP4z0EU2lp>(lbK zkS#>cl|8U7-qG)hZ#;^~+U-ww%)4aM>siB^gzNm6t(Kl@++Y4HSg%^8;J%;(1-6aY!^3m zZ0aFp8)`&pglbd5H`E)4vmlftw}t3Z3z&w_Mbn)s6P&xx%uj zqfVVg^c-I|SG-w#eDZg4<$LcEvOi7!+)CwQ@th^y;#)H+B9V$2q`JGKi$|BBA@Rxi z713zLIJsv$d^{2q!009?LkSn8d*cv6=bYa5C1F=~krOBSAm0*MdQ*8tHHZ63roO>F z2`QU!uWwD{w6-8}LVPX6(n7|ygjZl;pVF7MD>4KbUE?++Q)SIDr?st96811mMd2Mq+5RHFAwYO+$IRr6DUUfB=ccr;bya z4mfH)N;5C@Xjli=t?uBFVZ>C254gdQfzSh`pU2sfB36>WN`dfLW!*{JB>>kAAVX%b z_#L_Q#^i<&nwdUh%3R5e&etLJ8mg~oDJazCC>CyA;-5z>##lvzI*nJGC^?r_tBtuP zI(#c7&aRrDrjfgU^`i!lGQ%e?s|a`Z-n?sZ(Rk5M&#L{AcwuWpq+DYuKAYz@R{aT} z4z22;JXiRya!Tfv_H1I~N2|J@6tDaXt-+CSjc?;rNw~)Mr}ihK_FgKt`6A=0 zO?}6G!g}1l%g)pL;!QX$^gQXP;)>ZbQaK)JPO7b?IX{>>keXA#$o9A`nLU|$7;}y> zttHL*!O1xh43?oI%jt7ce5W+$hbKQLowKcOdd}^b^G&9=q&YtnA548tI%hdb+mh$L zOT15RQ@op;Qz`oxIX3kZlo%nEF{u{s<7yQjVnjE)=8vb8Y_9Yk?{4otFW=)u0)*M+ z3#WD{v`mInCZ)~3kjj_XzB%lYZaHYIrKg z=|7272fYy__e^pC0iNa|M5vIUJ$E?q^qToHT1X#SS+u5qX#0CtXT-~E6WVg8-(xC3 zX2V(*^^`TE5UN-qvz=a4k4pQ8GEgK29<#+iDFU1j%j{&+n#i1_6ix>EscwZ32HkR=JS$Niu!L7#UKZP|3A>l( zhdiDT$4%_mu)%68ZxEjtUv+!5JQf?<{j9&Lf6uj^=#GBU)lYuuiAFu1$1DBYW?!;l zV_8E*yZF}CyFbJlEyc=7wZBUenE(an%9YAuS->tZ671qUPrJz-F7^WuoS!St_l8mW zNl6&+MTMtEo!8E}!}%INwJB(9-n|IXCm3Qb7(8=AuP!|N3_QdOK!&LRs?j8 z6WR%}XM-MnHrTalsS}qkr#1twxiPWurN}fCb@A2nmwM_9MYR66m}I1JL_w~~0T+Ma zrHN9Hqq`>sJZ%r_O)iAX`^oEE6)gdt{DoLka&CWuKVMPCcpM%U1@10j08j^!a2P6x z68|&JvWa9FmO|zf@=DMvBhQ`2X`BX)yOdqz5$Vz<5lwk#m|he`i%D4r+$agwHcfNndsj`ShII$&I%! zVZ2l4iC5HZ)Xf{FJAR8OC^gD#?05-FaEy8bc>Y}AmcNkGlK?CMJs)q-ldxs-D>@p8 zrR|AHpS`Aflf1>E|Aiwd}cxmnrmGYSaTP(a)Tq}dP?WW1I) z^JsopAk^4P1b4eSPZic$H0`Zi38<9j)Zb2end!*AE&K zW!)U{pKsMxWM+Bn7dQ-Bt+;aXZ$!?kR)oz)^h+-2@dao8^XDf>F+P2nJl`<>Fu!4~ z*tS;Oe*ODrIqUh%iP&8k*_ng@PONcas}0mHspS`ylI~KHE<+V^ zkobOrF4&lCrNU03A)t z(1XF2DnJEr(q524nv!vcF_JaMR#mbMAW~>gq;LC%F5KQ-7tV-RgqOB^EF}R|?>T3U zI(lr7LpRiS^il5>|z3a0#pO0gwVLm(Qhn;PBLx8#0nQ zl;+0{GYu}`R6ck=>CL$?&g+n;#z`|${VmP-A=!57j2_Rlhl&~H*-U>+Gk*B_DKolU z)8jTk>K#@pFe9)j^pr4tQH!&4gS=Gcmjx5Wh-C!}&HCyrK?dgkKyIl`6OgC-l+_-{ z`GbJxW3MADaeR2P?&vY(ln_Iq<~FsYrSch74o>^2{!&uXQSnY?0$#+O;%^|T;n@g3 z-o9vF?TFAeEgUW|6wX!5ZP068`r93RML>7nnBE^L(YH2UDCXH`4$MnQiox3SrQ8eX zRkk#0n)wr~zl4&ZF^W*qn)q?jnka0AHBsM@YfP@cgpaueBWFt^r_RSZP^+wl+HdXc zt^gg0o$dmrWi_IY&9XI#bg#X}tXHcF1T$3ueyyY3Tw_LBsv0^{DqvN}R6@vIQ`1_c zY2j7jc(f*5$CcZ|-W+{cqptL#%jr9ZC{`5Bi;>$wY>#Gk4j(~v*kP1WQZT}F2|8BP zMxhtj{8&w@De!}>D?Jn}mY-@P4Mphy&&0{og7u|6@D!_K?soBmu0cL`V}w%FMV6;a z;0#sS6=m+oy6OuuvgaS$(if`?z89+hy1pB3h=kV2Cs&AHs41znYTuSq5gYR-v@v&I ze)=UOgK%Z}-BqztMP4113M|V7R8JghRo`nR6SB8tT!t(rIDB4*K1Xobt;T{hK?Q6X zaX1=tH3_pZY|qXK+tbtR<*10~RN=ZSDIU7kd_rq>i z_;)39GquR2VQ)(KBkD0k*p7Q&mfD*c6u#9`otE00LsR<^Kht64T#Qu8-bc8b?o2n0 zpY`?Xdy{)unvqHyX~qv^uO@eUu@@r)?leDoLhC;j8xi4 zGfLH9^u5`Pe)sfeq%;1SNgHX#4^y9!&KM8rr)LzKae6+Up7CSinYtBR1#v)Bq^RR+ zv01)YPFdwJ6QT%g1lDWk)V{Q8<{8AK6H3J7)wu@n9-8Qy zVfLA6u&b%5*qar2rw36#5$9;hg3Q&kY)s~jLk?ZajL3x z#dJo*YxCvzb3w3Q=ExQ%8lTK0ht=eM^-t8Cx*$u}UaRg>bHB(WahPcdePO#Ik&)A` zFyoj!!lB!VPNveT%&Pt9;HFT$h-b3Ve};J~?;adJ28S6qGT2wsfCcH`(*w?oVlKGN z-d1ldDRmA8dX?qi2pY@nnb+F0taTxJ`;a;KWb>7`$#ke7R4c)(W7rQKVF;}!)fw%m z`^I}6aZ{wkv3DpdQBr!-s0YOa;7oAy{k1)9`36I_dQM09BE`QJuif5JVl|c&82vpV z8iqaPJ<1dLn!U0|5TVae=uiePUB1{6olqqE|~IORbb;EYufjH6~yHXlNf&0hvz}4$;e?kpyON zBJPunCqMweHlS<9KXk#)_IOU3I&Yx7HebDV%ZFDfj*l#xdrhzSLZ2Z1L%7X%MX=oW zy8jB!f5j(P-a=2U#6$Qdb^;>kGADQd&yw8*gk%eOkNX1XI{(&cvNb>^I<|G}?%3C{ zze9mUZ9rSC4an&)J=Hyd-s;}KNcBiyYxUN^{_6dK4C?yIhR-~c)>AeCAtYzLKbjHj z$NVxavci~O)<(X;>s3?tr`^Xes=Kk|KoQFKBR-7yUC->TvpKGCHq3>2OJq!RND*b$ z>75}(ua^FT9L6rEsMZkS%R+;^EZS_Kc+DhEk@a(9NKugJ(07=wB#RK<9Krb7)*RKz z@u>=(B(Lf8NsVKTq?0Oe8&fB>4d-QMvyp*lF;Y6I=V2s0spyG95R+sl%TBS54S@n* z@~ldypYj<>bME5aO3g`6b=$0Z26mmElj1C;Id_qT$vKMy7#VIleNL5Qdd@4EL}7SQ zS0}}bw$5cTMZ%V{&&s&Y>Ac`N-;~6b+MDUvP`mvkwp5ZVbOj(;Aj1SAr`Xb@9HG|> zIRaZt=*3i1%M{lr?8+fX4gJ$Hy;{eI(Ks}YK(s^xVxW8*On0G=E7Rfjd%o|jex%w| zH$fB?{0-%{xRR_@G?_*TPnoX=rp6Wfm7Vb1FHUq@8~u%3ZX;RM017#>ZdA6he^6LC zyi~~T3JVLZmR#^)WXe!@vEi)Mf_z*^S7|oH5`v!_YnZdNVbIdj&|lSHwdChElvre5 zimjoTKkYmC76*Rlo5LrLP9CPV-+?1@lt>;BTA}hLSs8;TsfxxQQkdUqQFWC2u|JjUAcwV@RdM)3SRW}= ztJt5{BR)1D9_dd!uC)eziQ*c5cKWqGdsZ;hYRJ~d9oJ4|6c=Qca%9Fo_FZ&m#8zdg zEbG|);}5y(EN8n{`W>YkOHG?~+6Pr7YmJn|+_<*nR=&J=fOuxzAJQ2z+lGD-iT`=y zK+swoY^xqxZ*nS!?Lj#inJFKhi%wG|#s46)ng_12`NG|W;Xgc(>C8yWZFl%H())%p zGW-tuTcvHw8QiAUg7G%U%KE9#+7v3;O@NjullPFA*%&X%DT z4!dutfpj&HnQMe@66;25vyP8DxQ@<7(kQIyAFhnA8J@GItT(bR!c`+lvm3v>6j4Nm zN3frbYjmpWOp-Y~ym+*`vAa)X>-{s_$Nwc4%PN3<_$K^K>4+#~nR zD~CIIe6sG?F$VgZJbDzckKribZ(xDeMGL%O2tEu8TYGeP9qPDYb-#VWH+&Q!DT-6Y zmZe`bPd;5yTJxW{aP%zH!S*#n3nD8JN<|ClMrWIyMm!Mha8h;}x{dXWK`IwHb^e7E zUry5xiF77=_}8ZSNh&WRZJ=NHe&MWhcV2%+Uu);N-v+D~{j|Dv%Nd)kH*^0eaMOJr_gHoN&>mPoxi|pwlmv@mZU8E~KW6kjL#cODHsC`X*brWq5wXf-=rcau_M4PCN zHOrT;I%DOY){hsFMPu{#^!ZAQ=h+P4fRxwG^RcaP;P_G8<>Qk_j|?9@!N6lDaPNWk zo;={EHyb;F{Q^ugO2uezT)aeabu3`Bh{i2Xex=MKNd!rpSj^L+p$KKlprIbGioq*R zWwH5h_sIPdr*Z(*)}BTJ6k9}e|K(1R*PhB6q*DEWHmJU3^4|a3{qi`p-7MJ(**e)4 z)OU0xmXqdXvJ#4<$jz^p3fp1#>m(hX&xIGdn_UIJaq(3(w~&O3MWo;eeH z)}OIwRB*jn_Hh|k7L4X6)LHHMhCShz07%5UJq@U7^rdu?PTx5lx#jfCJ^YM$=oksH za=<-&)IE$Gqg#6%+Xhnh=!uh?3IJ4evmJgL`9}~wQb-O^i*LK7ZMFzBWNcH>&BSub zY*$S~a-?BAKJfLy}DM!3WUzaRdShEa5kKDumqZIn!z%38X$nqLX`#WbZ zv)B`Z6HcS2L?6pq=6%ttDNi?6&CfW`+%QAOXSS`qU`EGp|JxmR?@iBcFzAitbH@kc zo|<#ZjlN$5GO99NO0a@el+>eQgKO`p?VCBd=>K--Jp!y%P}T*k)k4{Gi7ijfBhStz zOIpdSR?^Z+RtjXkKsp3+Sske>$keu1D2Os+8{)M((4s-{cCV@JB%M8NAGdLBeQV;4 z?)o+J2iKU*pqT6p?F-4PL)${T@ykmgMQHx~MI)W@&UpWxIm3Hmb9(l)IE;IGbX$>X zQdiGIN#5k~V-$}s>6}wkPD<6h?VF^E23rK$=>Rk{L!h&5AYoROd@4Rcy{|GSRn>@* z$&v8BT0u!&qgD#X5U}4_5TGwl|Y(VRXi&|K)8}o>l73wcjA#-rwXb z%^%pY26L3x$@aZaKu7tt9-;|dr+po;bbh%6P<#B6z z9AQv25qbLv6W+%`Q745Nr3g8-WLWQ`q?0GvfO%5TnE9`A(^VB_TV>(QvR3hDrvs(L zodCIR>9Sp@P%X$UaJCpS;!940PCZvzQn=h0nfCvbdSIU5|53jW-kA^CPMKHhO=UZ; zoVrb!1>~+%R!(RYBSwkOV-$ExWxd+o-rkYkB=h_$QxB=uVK%4CP0_t<hdi7dIbRy7O_&osiHSsVb6zQZ#tLmk>N8eO zJ*(W#M%7Kf^8$?0Jf#hpLp>qJunupEGB|8Ue`AMiuR)q?g3YCE>uF2QHFfROcYIXw z8+bJ=Q%r83DuQ=Ykf2CX0^e1QnuhR&{cTMYT^{1;xTIC@R(sz5D`3YFN(0{Q%tZRiLNZiH#`8%g1rFILa7fju;wn_&Vo(0_&=7h%uW{sP>~ZxX^;$KrrU3_7kqmcooTAgg?nT)Z{N5bDml~2(`X{jsJm*yM z6gZSL5C8y9g7RtlSh2IkBUlD5xVXFN`j7L}V>V$VzWdtid-AJGJDVK&)xkI3?yQWp zK1GJe^7{^opNWgAbazCDYZo6QF5>;X=eFU2y0g!n{Cx5_z5WRxZeCG{SdVJ99<16H z88RiyknytFQ=cd)Wq0IQ)ZHTf zwPllN+QgoH^k@AS)Hf2o(H&K6MI2U1Bh~mmxzrtzqvppQ$&F4L-H{A4eIY9wHD6J> zR>}H8tPL_M@HSRXeWX09G|O7i(YvNcwg~z`UMMItA~`}{B%$n8j=*MZZwNDTSjb0vxd@$!(>Aor4=@r4+zs zCyP-b*^3ubQjOY{JYraq`w#CQ_PCa=!QLWn&ngRNpoj((s- zD=frqAme)C){}mYpbR-?B{5y6j*~^qK_Ux|1i7GJusS1d!J03WSml6aSSQe}m$zE$ zG@9B7SHTr>N~bJ|*j zS{s6_9G>E#S%n@OM{|uB2ebjr5oARXb*%GC%t07;F4lr$<6e=*{X-h(rKo8k=1pZM zI)U7SO@#M7!p7Y`ty8lQgoRFRb~Dx@rc)uL){3j;ZHiX`&j};@P}?6O_E0d?65@xf z#8DV3Y%K%~D$^Iy3i?P@uWCLCM!|0P1R6A)Ch7_2)7T@8>rrWsz#cqe zlnT;ZJnam?lJP`~_z?m}xb4*0JsDA#T;5bQ6?+9i4?tMJ)Qh;BylwKY*DpjJiu}w4 zWyZ$7z1xPDR^GE<*3To2=WOlVyf&XB@*T6f$eWY@Q(-Yh>WZFN)+omB>L->jg4AvhALCz_n_)@KO?XF)L}w%uR(o`_>0 z=w#PT43hdzNpBk9Np`bkFtJp91^@az7j+PYLR(jUR{DYkD9(wMB-(3hd)5@zSwMTl zKT|Gl7GK|2*ch|uTXM?lUg_TO<(K4ILq)89$FKH3dLJpDaeab@xn(QG#mM|+qS|h8 zqISNGEQ2YD>ex)ult}`a#F0r#)PQJ_f>I%8k!!7sbIEe*eVS26U3OWnP*fKdss&d# zMzs>IjixN>qO>PZ$AdB3QMJ~)D16f3uMX2*sLu;ySm82t!G~gLUL>5Vp_-oA( z!)Rq>y_Hz0S6_t0m$gX4$1=iR92ClQ@)Q2wOTg=vWzb&(<`kdMB1G2*51N2)mQ; zlLc!2zDM`P-Ezc`Hpx#<7n9nkE7Bex@n8|>q!=)o?9U00Yi?hi< zHtEl#^+^E@*`g+P^j+ZzS|(TtF_coA@H{PXX-T1$6aWBXEir_ZWhLP}AuC)^pe+?R zO_^2ztv3}KCoM!8c%D2cL3dKRgl;r^!6t?PG4mi!2!|}F>sN6Wm^dm}!wMUIqNONA z#h%Gm#W#13Uw$VkB&ut-zNQm@_U!83bbaL=prkx!oA`3Sllzs6_Fm7@Hsb0Be(9iO0s;h$g+Z2=ZCL+*iZa8p9Rq>{8&l2tb1 zR>4gnBW~iRYcwOPBjF}71sN$LZnehN1AZ!&t4#tRdjXAub*(9l6zC$Eqvir4E6^60 z3-|)BTkYu55KUQGF-1dq9m?X9XviZJ^N2GzypHNxN|3$I2P7n(WVCB;3WlU>G>wOL zvg3%|#C8%SE!C*lUirBIXR}`^*`GY)2Uy5-bVdkg02@@!u#jJjkMI2tSjdKd)KdhL z@0UU6D6w1P+J^u!an&2=#)v^$K!^ zg3L$T3t1BN@(I!cFO;g)rK4LicV=>CBQBG!{QB$>9_1cb5I0j+sp_5QRr3C5r#LNv13F4kKr8l`oH3s&t?61wkNMp{l)`s!nj^Gx3D&T3=kmoPD+-J3 z;TcP3&7>mx?*AZucM?-aUQ@>)d5(Haf9x}4WE2cJN=yZ%7oWG532kc8GUS>(6DtLr z8SD^~ILg0G{Ez6r`u;C#A*!sZD0QfUCsQ9Q8l>*Vb))Z^s%q^E$%}S1sqe@X9~FvV7ntzuGmc zg_D1=qrHKMpWONM?5pfcW(KnvgPAp7n>ZjyR#2;2B z3LNf`n~OP#+eyZ)WGSNE8Dtr&|9mD1k$j^d(^jPm_DX|L zm^EtARPsuJY9R=Sf1F^2p4b_zlA8%s8dRWPOk+FfrJTA2{%yNR*UUfVvukggSUEP2 zY3S8Iaz~hk&hd*U#xA|&hUb@VzMfy{s2zLm-VKj8R!9mt;-(5Y6Ks5%G*{=cf4%PG{TG*!ir}7ZuDYFyN+X~5+!kvZOa3OIQ))sOdG#O21fQg$YEj+n}BbRXmm*_A= zC}W4c0JqX^Mud!F#HWcGPUhX%rNP~RM+|a3=ub(`0X2;5usJ7LC7p*V^-t%W^PTwh zn*Kc6pEchc*-sQ4dbmb-?tu8o8{+4`fcMZyNFxm=G>TJ=AI!d)+w9t=!x0#~k7@$5 zc!fMJuYu=(C~>K}lBC;6VGaR2ez1lta1*djFUTX6dG&eR85x8hN~eO3gT^>RPuAE- zr;XSuX6i{xC8;b^>tU_0qCzmR1RMt=MH59_(GuMB9KS<3Rz~{Dh)_mq%80FuSoMBA zH>_T*=DO9SUQN7eqOR1J$+L`z{UXU8rzGUlUz7{i$MEvnHUY;l3-*tU(R4e|qytbz2wy}fvp82saR$j+-6pVfw7|$;%kA-hp zbYS%dcZ4gnSzV&_{6F{HX~G&O#O3k{WVI8rU5N!h36nEI1lZv*o?IO!v%&x+REN3i zII@_d&TUkvmc0Za5{%d?V7uB3k*#KuFcY&ab5t48nr&plw%fMP#@lR-O+mpXq|3FM z#yVxCvWRY{xb`0hkDQS5d&BGMsMSWZFW-NTV*k?_h?snU*`-n@O*M+Umdv$Nwp%{U zk%vRl4h*Q2Idt`;=3It6`NY!AACfc`-F({j&s>&I-Prta!+I5ZlG9egDiygYXvU62 z0E&CzySGKr;hZxIosK-7hg_Z~@Ax!9xa8gx6Bmzf@;*ayUoWV44`RET-u#vL?aMK7 z51EDCJ9sbMt&ypB6%WI1@yjku44hLzHXF&x5^_l~Szk;Bi!LtWz^t&8Bg+XHEFm6X zc9lx|C@@l`yG!?#%1aBfCcp?&5Xr`-WV||olCUyO6DSXJnt)Gf(P9M;&=U!c4I1Qg z(;USS8o^@TkR)eQhA*?>C^~}%t|$j4R!xetuw&|Du0Nj0L8-JJx=Y%BiigF{(HR4I zeRqrhSSr+m_{LPm*O@{$JR0-FvQ_t96DupMb8X=lf4`wRFm%t~?*w=Bt7EwZR(1Nz zn-45~n7gjBxhA($d`rBOWZd@qq9sKYVd$W#OHiw{iD7eC1X^~bct3Ozy2NJ}WP7{? zUXQ%T+~eU)W|IePNR+ zoKeZ^o@N(3Onr2!`>4- zq6AHTb}XAii?VQoU@wL>?=2_gc2#CX)>@!x$q^FS;iiVLU8vzeO7qDR2$HJ-(f7OI zNHY8n3N2x)AgoE1@DZSWBqb~zE9Uz!n+1Ua3e3TODdNjE0wUomxg^$EMpFvc!N#TF z=6q0n$&};gUiVg6=*)B5>czW;-p-K_%J~KSv*J^=p3u7~V6v;W*3}|@*0zezy!#fC z2|D19|L~Rg+bV0kHu2bvcaoL8zqytom1`>`Zn>)nPYN~@?&8W?3Q=~u>hj5^=i}mW z+;_&2M{#nbhOOu>#t}_%avnm=9xT5%W@IIA*e6(7#-OhF8X1Y(64_@534e~C)cFZF z?jd%XSm+1QgTYQMnPwC5n~2>+(+(Ylq_&X6GRP_=8B&riC9zvbES(glliW0!D{h2a zaPzxwv)YpBpq->T+|(XI zNP__%sS035SWlHrhw!ZV#90fY4L!EhsJ#nIzMC6#eYX_3C~iQ9K;_mJvLO+~nO z$s<=>k=8e`W!b9Gitdt%I>(gwr#G*<{PmB>;7GkS(w3Jl|7De_tg9(A{r)|-=ll6O zSC^rv&|vU-&s#VaF6oRUD%`d|@7?oDauKnRTD^b0ANPRa^%c*-mP8Bym7tDrQLMWBOsS~Q_6n{r&kUm*&!rR$A)I8qI&lEa^dLbjHIU?)#*@_|sLe;EZ zm?-_uuthVgGu+S~PZS6d>fj=3N}XJ0w7h-d#9;;~L8%JGxuurb%6v7L>p2vCk0r;l z!gNX6pjcCC$-}5gYUDgWRvKcG5!@vi1o0PWp=VY-_t@26RSzt5>hx!18D{q_pJ+EX zYc;(CuTgtuw%wyC$PT&f*E_g!e@Vem8EM>g%b_K`ulP1_g*zI^TJrPBO(USPd^G>Y z!$0Qc5floO8(vx@UcBh{V=JiAstjJTh-_K(@sA2j?r6HrWDzU*M;?R=87utpld6ss#F>A@=pKe@6*Yxa1 zue}a2KIMhC-MOcqx>N(V-gVnK+sJd<=*^Lf1$eEF+)N*cK^;H&{WBejv}eW3IS#@F zH6-sVeTpxDmz$FaEbAsM-Ke%B`c9!D(JoY&Mhn6waKa=IbI?RoVOdX!My{EuAMMNz zcejTt!eJKBljJZJ#3x|gBqcFCA~XPi7(Q7(J$>}Cuh0YG0-DqJe7H?V} zgXm5Y$jU0YF=L>jjugrHBHz6eOJ;eqvT}{JXc@8tE8S^)*C%y)(E7%Gxa@NR}L_ z!-l1zmP*^4=(z|GO9!6u31Cg>65^jhWk?18uq%UjavBa63 z8ak&5K)PcUD|2nxs>P;gU9snDl3wRp#g)zPt>(o z+>z33tXoVkScM=GcXmOGf+o9lei0XhF-cE0q$JZy>`)JbL<8sfhliORTYA+jE6mO_ z!dU-72Fl0py=D?e)}hz0%F-J$3zl{fZ}<0}aM;r}c}S5t*GBw1ANcvQ-k*im@kJL3 zRO)@RX(c_OMc2Lh@KUmS$@-FT8toIBcF!;P1!s!KpKc1IIja_m7w~jf{SbMOWXk1~ z)C#~l42h2cccDUlu1D6CurF;Pwn(EtTt7ny@sUg+)Ta}Q+Jv&+dcno%((=_^ps>R# z96Jz?e@=iZJw{_XFp=K=oWfOTTragl*r7uvTp679Kp4;qQ3@PK8x4Z8eZlq^PkEa7 zkYr8azUI-F@&h`>udsUHfO$K9$)IcGT>KY;Bm{MyQ5q*I%lraSrm>o4Gd_)O-=QBjRo<(B#YYg%f_#6_`*E2xRX?Nox1`t%)f2y3s>ymqT!h@pO|UO)BY(|J6Ksy zN-nxR;;s?o`WLG{lQcs%eh=&Hk`?5O5 zon(QPAVxQyLxyumUj{ilcxjOPy@rfx$an=Y*C*<^dZRs3E7SVTe$Jn*^rGb-8b~MV z>rFy_euWGHj%>J@aW9k?Aacxvr66@F{)r<393@5E!l6hy5=lo>N)|8;m0VoOf=Y^3 zrns1=!4Q*D&_hyZ^j6@8<;fRMK6d$)KdE(hxE;>gwJ*t=DBK9(i-Ius?eQQGQD<9JFicFz>Sf~vd zwGLxpv14g{Y}wj-etrH9tl##j!-_Kyo@|!Qd%87F7S|H4mgbo}@B4rRh%iur9tynvKT}T_nj-n3B?e zY3s2{rh1x?qkL~{KgNj;iU#T^Wf;-@h=oAOxFk^&XQa!sX{-YHtmxLuf;T?lTk7z- z1&&xXM8RZ;0szUZe~{5Y$83wXcd6omg!p};Q~a=Vk+^+?%8A9~qQxCI@0xAw*>+j; z%i>h$)qzMwHn*Ua=>M#13Yh5_Q%yYQinspyDOpYW{bTDL-BjMPRid4E2+EP+w^H6L zNjD39(9L~)m6D4^Bz+GF;*%{+)Q(n>B_2|*qFEXQ*<6USG5iRX6b03q$hLyr1^bYE z@mE)ufz8UOhY;|4!VZZu?^B72f*pQBc>=G`hqQI-uy%Fi)obHTZtLPNrvl??Vla`EO(qQeQ_@brc>M@c|ZhVnC7axqSkGf}O z<)wS~N!~?asVkNqbG`Zf0o?zIA0X3yh~zsBjfL?^G#2#nuLTM(p5KG@B-4>ixYVD{v9$C$#c#0Eh z9j19MWszS+@g zYH-ynuBaS5MN_xL6x4d5!p5m8bJ{Ga@`s?FdS;NpKd^O~j>H}V?}c6xOnFLK#M7Olkhe5$ z7XKm!C4-kMSu&)S?A^&-8iT2*%^4`lCM%pC#X)zZMZdb*Mid#Uwk&68Ha9dv&RYcA z_RGmjm~HEN$bAL3a@QKCwZ5W3{C$`B3(-$zhQx?voV5v_TQVOmr&e!pj!w*3$N#SrZ2s$0-#0xO< zq`=B4E^2O`d^C;PXsR>2#TRzpnMbYsyoaY;LcB0Oonz%k{ z)=b~cJnFf~{gU5u@?KI%<9~V{E$8y{l&`M*==y5fG^ z)m(lSnbEIFKFUU4*g4B{RBag*v02>EB68lyijkKlePjof$6%U{O^yDk=>D&+pSR3(u)!A5^VQ`8^DGX#zq|FksL!ufRBhiSrFVZH& z2YLp$_`srptpmJlKs&$9&s_#>S@$C5cv0&K;#YfgwUpI{*&0 zYWV)cg=5FyzgReZF4Nk1s542vX)!$?x%>)Z zS*b}r%3kU8$fpkr$D^$LKOGmX>&K^`mNUe_M0*4Oza1h@=9v0Qai8J@^AGD1cIq6C zyLo6P<`jC1w-$57T6aVi^9o4#S*UkN#fRh_!rVK|qCT)`{@pc%pp+~bX28Hrh86uE zTtmfu_g+0&GqA|cTtiI;S9tA8V3)(58N@eZfo{-Ad^;bco?&=`FS?+GtRX-D`W)sN z8m~U^*qWE#ol7{LhJ2JeZWcdduHjQc$~AeS1^7jqNY8eD z>EyDtUuuDWN75kWEB_g_3m#yp%Q{U%rg0P2qC(K>g?#wPg@V=;L7YEan9Efp7lL8y zaOl`R`i}ubNr3+6i$C2jE?jbk?*GRVKASvx_VzROi+}i`4~$bXcj{~TuN6n(3Vn(G9cCfAZZn7tHTTJ=J?Kr!(gu#9Q7nruW!Ypb!`oCQ)-AHJ%5FIqFm zP<2XSyv)8w6aWEIJaL3tuqnbL*r-Stv0F>SO)x=lTJS&VOEH%hY6Hsh)aT6lJo&Gm zeBmqc=)uZZg|YbB&#v9RDW|8{dX4RjuwLg13v;iuU1K%Z*(bLC?BQXfxxB9Yny*OW z#Rs_`{r!VaFD&(y$91E(UVR&n;~Fm)3QP+A=bLx7=f%q_P3xv)f1Rzg90tf1@}4_`{|&bOnp1K9b)6Fn2j{GWR6T(AOY;RHS$5xkWW= zYq(eqsj4CAHDqNmnO{s?#biWJ`t+n(PwLW%JDs%ni77XpyEd24ovZFx0*5o5EKDa| z>7*hzU9iIF6)FX5J(>v@*5&3_2n5y|IV%V!=4Ur4DfJ9Q*v6%W#l?jwmrl*vXubRi=8Ng8LYH+jx@0+`Zu?;gn z3z^swW4vka!@U`Rqd8c59g9h}q-*VTbyF^p}^ibin|@(s{~>6#Y`V7+eq>fn$x6G~O_oCV?Wi?+^M zyDBfe(D+wrPHJ$T2Z-RLCc+R^om7~hmFA5Tv(amab0m*S40;_3@+uSwfu2IHz^y1xbs1(-E-yT$qdD(Kg$SXqQ5T;rI>Q=dmyY!XWH>>h^HmUx) zh?m0)rtb2u3*HW%hHT?1XhvYHoawnB6~8)!;mA+tA>L6fQ7wL*KX7`WdgAu1A9 zgQLH&a!eukYa(LI%!n-!WQ32_5P%B7p{cT5Rt~N_T9we<9Wt(AZE9sMH<7Dg{A(C( zYW#x-Ok^w8rr@INa5#I0uKqQ_#Lz&7kf+duMZXdx_49v1mkNs@rPZQl?~EnmtP{MG z_u>FeqG{*~%bgtw5qIN~Rmw0F6oy*B<(kvPA)6%FhoACRM-a|IRw6Y4YAaVKCy4<9 z&TX_Tp<)L3s7tiC=*@8HrpU_-G6Loq!tbs=z*Nnob1;kGct^s%#MBG}E}kk3UqxS?)(SOs|*~=ONn~uhQkZPZ&#y^Rj*9Z-lo5fR41LV8Afj(2Zo9j{1bxcqC@) z)Y(#7ANSx`F;BpA_ABlwRs^Oe#H19=exY&-yld^yIrbzr1Q9~6cB%|C!om1mH4dmn zgepWR7o70be6_VYLg5b5m!Ha8P6QSOlGT9^14(d}*qt0{n+>(E0|KMrv$K#Zl-t>k zvn7WhwMTi%Pf<`0v3@P{*F zF0AGPxdQ*A6&6svkMS0EafDgInmtVE*^_uUo2s>Aud1njeyTDyOyVyP)|J_k9P8CP zqP~jLhG=-mUb;>iqS1hJA(=9z{cz^|QJv{37xz#E+YqJj##h_DVzircF$qN$szck2 zDR@WIbHr7GJYfys!6iOr^6G>39Q2+E36fB3y@a{!8@dDjvw?sUmn4rRV$j1FBv7C# z8OoEPI2mf=qBag1$3a>JYLOv@EJ6g+ZU6!p2dY4=z*Z{;RR+Sb>&Xzb&W;hNv0pmn zYH(${#>T|>sRRNq2iVoIAznme3N${M+jqfyc|)wj zX0{9nTT-&Wty-%-kp$`o}Dw?e@2^!Bq&*Nmzh({n#3fWM|-vu4wqb@#bl^}_v)DwAnMg*ln_I(!!DF&DSG7gI7 zq;W_Nr%OFsO^yU_2?d`owxOtm#A*svQK;Poweyh+pW?evtPp#lH>^TJ3>RZH#wzCm zp;l8P>6lJzlY_A7s3`cYs*1wr=osoMd)X7}&{$bMYfb$)viY|Q-%gwT{%@D=7{k|etY3a`Qf}t@0a&4{Ls!|`+0GE@T$F4r z1h-^9MlF1G6gKbq+BsxJsqEDOTCuCzTP0Q-e37pQfO<@b%0^|c4aW!v5Ddh%fZ+)m z@c&jQ(->YQz$lKiy9j1yXigN6js>~GO2L0Ny#;@fv^cjOizpjB#?`WOK_?dr zRR{JbC$(u&o))EPkk%V1y-~Y6YIH_r*{C7~m8nogWK$$5RZFx{+BgTbts3lW>bSV{ zaJ7LrMSKqZ;l-u|wpm0$x*AhcG7?cGXg) zVBhj9<1)`2s?1Rp*|fG!O^qFFByAK?2{D~X(Gi-qWtk4>+O!vHRYJ9dmCS;Ao2(>ft)Et+rsz0|M2hRh zbri(=feJ=s(#Q{<10Nggl?58c`|uYM(8E;HTguGxK`j?rt%w25NoDa21m{YaCKt>a zgYy-=t1yNDh_s4fAGM)f_wBOA)}|&8CClO*#25kk=2XeMM(1*cf{DS2TzjEldRpMJ zK)jp$Msc};Lbc4!DQ;A{@w<#EBfz5)WBg03 z580{Um70|-d+dScSR=g~@&c^SRb$0OBp?xpmy2+N+GPSemM|iSYsU~xdmNlhJLd!Z zfNB*`J>FBpYAmcUB<&e#3Cfh2G_06M!^nhAMF%g+`VgacZttP1Cz?S2t%#VPFmjB9 zZ50>N#NkHbmncS@auk5Fcc{XIp+e(t<;5WpF`loxITbmE#2oRcuzG3nB+H{9|3FNPPlj5n7QrG`vkWXYE6-8uqxDitTnu2i&ds6&HR83tT9Lp8+f__v z6_a5NUI;b>UPPL2$4UoAp9Gd`c>e#mg3JPfg5~dv%X!m9C~yy)bZ{{Kpfuh=tO*Ix zz-qc@Ck8RA318<_4u51_bea~3SIcjKU$0E<7%$^}@Fn^fv-^X;8n0NfNkkS;FfXn7 z+J(MWPk)1F$9RaF4zp8E)Fr!yLj`TM+9z3^uFkhs<*xsE5_?PN?Ew=SEsIZ3oKQt7-8>_u8*TqDCefy#?O*4X z3&}GemoWGwzR6CZ^?NDFvO>?zo+mwlGlDMV44z{aDyGz`!XC5AWmpAw1^g^8G#uiTXRwaNGT3VJqi2GXS+}P&h_Q6 zc|y*3p{1Jv=f4^kL*e zaqaA$tSQgNaD^_J!LhbHC)dp8V`Th@tCOT|Y+2F|Bv720LmzOxAg4hjm|d!%a#miF zd!aiy&i!5Y&)iv1jio}H*jlbmO|QvSrxvRzzD*4gR^u2Tt8sS}Q3h%Y#iFRO#IpjH8rq%@rYKrdE_NI59F%7Sg@x|9HQw}gTbLc15YM66u%abR227?5N z?RSNc1jhGI52n^gjlN=c3%ig%JvkA z0D$lt$vuCZu=tI1^-^g%awwrNyc`&rL$cWm9rbg&i%?)u)0oDiWXgzl4N_mW*fH-* zuuUSO1*%}4f?5sXgdsU6%^oT3QH4j72MM*(Djb^}$snGKquK*MJ&%a=5uX&3Vy(#S zfE($i5_uc|L#;N_G0Cyrk>%*?6HJLCt;Q^>vZjFUEy?o=0Sppko zw&^W`=_-Z|+VjK2gqTow6gF3#nl{fkwA~P|330HmYMC{%#QC?3v11D!IOU|xE7yB_ zhA4w-E+g-W73lKUvzAE3i7?N8nHiI9$5q=7Bxr(dDF0x;@}r9|HYgoB&HaL{1N~Yu z(UY88mxSu#a3aaHIHZQ~CKB}$h?5{rAl;RSuS6Pk7+;|#QoU>Zw6Yp|t)1FAg%3MH zrnR$^I0;h{;Js6nT8dFF(P196HR)+<9T@BASI5#O{Fq-~rG%HpQYKI=8vTN`4zm{+ z=4s&*tk^DC)cm_V!u?|5X5-NN%QujoqDq}=uC*#)l*o(ZS&bgesWGXMLktR=MJcL;~lRwuDiL9R11_G=t|-m=IA}DNinSsaX}qy4=6q z7_njE=9Mo`&CA*RES@#Lq3f(=U?uT^%xUYAby*>3Vi2kgLM&|%B4dJ3U=S*EMOs%> zEkr3oR3<}B&WM!{f!TIWI88*QA0(;atNpZI;h@5_agb>vo!Xs9Z-^`ufdwfHw3u2x z-;X5>w-bi>Y2Cqj2B$}R!Y&7fBwVVtinh+tSr6#!s%FlYNwvyIuUL<1QrH3c4-9}` z05hzn!^za>i3M?qwJa$#ED=Q0h11ej`N=|)QSK0drTfx+M`h zh@^D33$cq&4oQw@+d)KGQgBjyA!J>_C57pju%Q#idX^EY?G+JIlO3wXXoMJi5mNI> z|9m9MNBP*FR>jY@5u_>AdRtT@EnFpK-D-hoaP1@%!?-rZ%HK!bigoO zViDjanvqgDLC7Yp3B~x?TvHD&hFchr1vJL>!6_y{)^K1M^G5IfTp8j%+BQ4Tog6)* zE_zg=MwSF+^?1&T2>0sr$mycEV8am`klb``w#wcx_8C4x+dtTu5Y83I4oz7;EmY-J zomNg(9`B5QF4(whhFT`@^XX)h({`*td|tNJ*>;U>i0V5l`wE$j70TXGcv#~kK)%7YT7j0QjT9w`+C?mpi0kU4^%4fNxY|Hquo<@nI{O5(>j%$XJp;yh z44PQ;WR_jQG6a(ZGYY_mrJ3XO&6g^~SF~s>gXYr=@sU#Y?BnT6h!LZF?aaR}P}<(Xc0i#59tY#c>Xk zlTbmA3$iT0=l{!y*P-vBlHO9z$Iy2^%qj^Q)laz(*m2+qo=X%aM_AWnsYT&hXGn6Q zmZjHdw4x*}riA(aK`KvSUb;5UNfpI)R#Dt6trf#RZCP*Tt8yhIj4HXzRF(Mo-`r=N9*_jeQ4UM!B9ElWfWc?w9cllF3X2A93W zS=ZN-HF-ec$TChYK0Ri+UwD;FTXZ0H^qHfzVexii_pIhaz?*&88RW`VQeTlUN29?< z_ZHh1ypxk4hAYatCSGk9SQDKt7lcm6-HR$`h*<=n#a z13W6sj~kk6yh0~Opp|!M{SJf8_*UysuX~2I7mK3iNWpFV$th8OA8*ex_F@5dIhng0 zAB{Ii`;$3s)%7qJCD-s=_$A#Xp?<*$Q;pGlzJTu+p?0?`=H7U&Pgcw1m^;z)2W zIubm~%T(>gR8v9;lnV4-*rR@^$#kUy4q6TiGgqe}78v)iGeI6r0>5&9Z?(OBBwHP) z7Wk_owc%>1QY!)TV@d)j=%Z9F-U54o(4@-%qNYs@N|r&WW*BMO#I(Ky_#N1q{tCzp zND~u!%PIq+{tJBzI}>YAY??^p@1UvYJ89FMghJ!nZdg3W?y@&iF1VuKVF7z+(YkT`21JJ3m_>vo{Nk9zax^}!fFCkgxm`# zfVI}$9-O?P70l8GVCSLBu<0;>!2z7;O^Ql70MgNcc}q+=8AS@S{lM;w&(PQ(Y(LM% zhK_sdv|h(@b!NiVQ)9!61p+b=;-|vY?qW_E9nHAFc)@sU^ONPXHjr%_B4Qoc;^tbc zLvI}Lfak^(Z$Bpya#T^t9#E!QOHg99omQwNJVYKO&%;3&DdVdAu#)vMes0W{Tb|s! z82`?5!(5mE<5g$Yex9(svO zRazA((nvIvhGnZktiLp9r3TH`potpPs)1MP%M-ZkW5W|54p$&j zU{A*ySwFMU?`S=)DB&t;9t(>2|Zppa67k;c=J+ExeVUjdeek4~!#*El? zHZELFezd;5e`?E){S&%-yB=3ST1mubOT0oWc)-1pq>pDXD1KNQaiK`cpwC)-t`U(x z^efjb$o#hzB3Bsyyf^Xqo)A@*tEEEZ<4^Ju(%(6!)IiD9766JKmNn=%tO!WE4>`k0 z4#|cBkx4giTt<;MZ(f#D!N}g1W$$ax?s@zROXxos$Fd%DAhbQNvEl#6O1!~XkzUqx6$K>kFW_Y;;?{wjATZ+VZH-KVeKBg zK&t$Wc1@&u@E-cfh*2(@L`;TpRue)Phv4#A=5ZJQ) zhOJ?&7>v0<2~OiLfMRC=T)HYNtv#1w(F=GqoJhzlGhl3|GI3>4ytOAaEFd#8JuzJq zlP#@@b4?C@ex9c+jvBGqUKA9Rm|2x1lloSvBi)juku3=?`G&}nT+^oo1qO5$Cd>WvAIQ+^3;vq^5NRC~|9_PFV zc{~g>I1xapD9~vrAj?lQSR7*@3Jfx|f(0eBDF9P9S=TDa2G_8Zn)i0q%o+Ab-swW)pLW zxx_qTKCysUNIXL<0xo3O)(;Rb5eI>K941~SULlSUuM$Uz*N9`pam0dr zI48j#_XcsAc#}9ooF&c?=ZUw73&h*RMdA{1nRthI7ivsiAwGbL)z@IPKO#ORK7lC1 z>rhGUCUJ}S3~YH{5ML6viLZ#Si95tM#9eUy{*JguJRrU&ejt7%ej*+bKNG(YzY_N$ z!vLH3jrg7TgZPv9i+D^75=LSO0dgQ#L!z(UknzU~@em(u`a-CEX#=sic1VQ4j~6*2 zCnSb^G%nz>>W18r2SopQfg80Ck|1B?2gx-9P#_9IQY1sc5Um{w*=E8~1d2oyk|PC* zLebz#6oXVqjWm#rGY*m)CZI%=gpyGTN=0DEgqm|1C=+F&Y?Om?Q69=i1*i}ep<)QH zDM6*E42?wPXcXketU#5Jwyp||MdMI4(xDnui|UXbjfZ4W4G==ogql$c#A&uc{Ja58 zKpm(PbwS1PiKqunLX%N1nu4aHX=pl{0XZf6P(PXld0Xb7xo94mj~1YX=oz#KEk;Yw z09uNkMa$4~v;wU}tI%q+2CYTw(0a51ZA6>UX0!!uMcdGJv;#edcA{NqH`;^tqUX^* z^a6Sj?MDaDOXwhEj5v&5My~(`c@-T62iRliI68q|M<>xK^aeVO-b826S#%DaM{l7E z=xuZns@h#f@1S?ld*}*!AANwXqHE|w^bz_PeS$tk*U=4h6Wv0eq0iA5P)YqZ`U-uG z?x1hbUGy#b4&6id(F627`T;#eKcb(|BlI)+1)LpzL%*Xx(4Xip^cW37eYhbI{(vw- zbRQeY7MHXlc_g0{kV4X$v>|OtJ5og2lMbXK#94_+XVQgqh1}cjqzCB

*C53LqhU zNk0fL3LpbPpCKh>kexe(429e%;ba6E2|>VeQb9(MAml+9k_xg=XvkPHjyOTalL@TW zZaF)>yQ7`oIlil5vY|oW#wu)R6*A4%#X}2HuC}{N&uw82 zdCbWc`oPYE5!o$x*aGJ3Hs(;kT-8P&_=R;f%-#HUbBjBIxv+ydj9{+sU=AhB$xiyf zE3MVnHMX?qcwMFjx0Jc8i#~A5IvU&RIo?*7+B&-p`i{o-4z5Ap3Ee@ZGqSNs*rqeIcXoBO!@9xZwBbqY)YrDR)$w)X z8yjQfifFaDrPgq|+S}SYtx{TbwXi@|I_4`Z(`J^bNinkTy6)DUJ3UnguBZnLv$bRFyl z_`}WaYHX>~a~tV{RkrC_8colV%{)sZ1B=-vFl%Iv!kpnAg-ye4Uat8$noSMs=K2o3 zzO6;qR@Yd|%QJu7Vr~?e8*QcrE4{6rrEjaZDl|P%yXk=nnFng854;iP`#MYwVaf1g z2s?+{>{9%~UHFB|m>2G5UbxKEf48asGN%7-=7q~lFWhZ<;qu`gg*{KSM?cY?Jly7V zXHZlW{WqHatK)9w_GZ=7guTXzC}YBPOdV;+PCe?bb~gLKn6o!Nr)2VQy? zbC#doZfaQ{2V!2_Se{Q|=~-dvSz+lp%F=U`rROM1&ry~+h_Z|k zWf>#NGDehTj3~<(QI;{HEn~p0!(;?zDB3bcv}KHF%NWD+5^WhH+A@ZT1mRvRW5igV zD#mh0jOC6P%TvWz?oe5tN@aN#mE~DfmS<5}dRAF_R#|#hS$bAkdIm=a(_5-7?+dQS z=5v-Y)Rr;SmNC?pG1QhZ)Rr;SmN7JzF*KGjG?pDf1X|$~=agGLIpr%wxzY^B8i<{2p@3GKSnT#_%&M&F3f$a|diy z)4ehBD5Zj%rBF~{(8-dk!LmRflydqI6(wjl=-X<#TUzv8RysXH9x%e7H$E*agKz}@ zu!Kyw;m9Qja=<@s$yC2vJeMCbH*4;1Hpq(H((e`yr=T7glG{?&TpsfcxRVo9HCGVI zMQqfsf_flZMo>jm*b`?ww|UR>1X&pWD+D>V6C~CakYu~yHxd7%Bv1Fp7AgHceQv=k zLn#zx>f_wY)Of}V`5{iUNWM+y-OZVDVVE63koH9*(s^ndD*3-B`I2MdQoY5 zT9`yu8>~@D%v~{KP~I*!8Wp9KD=7M>!o`M)rT{V&QA&+cQ}I9l1^PBWIp-i*v-%dp zye}a8`iKuABo7;=hJ{D;dA`IwxJ!7%-lqK1l8?J@Ux*4hc=cC)W%Q$Omm2xj?_Kw( zIC}Y;U+2HH@zlJ)d(%dVI-4e4oFE=NH|p2m=SPiQ#U2c=u^-jv`Syer*Zf9BUc2PP znH}@mioJ*PbH4pP&hLehYp45eXqkH|Cv$bv;hizp9`nOLIILL@egy<1J$(u!SnyoB zGTX!{=a)H5w-+t(yL9!CV`$~ww6BDdHtm@HXqQ!o_m`u8xHS9rf)#n!3v@pm+VNKg zcayT%5r5#FL;Gc`&P)!Tz3j%& zYxSvFJC};SI;s18L&?|6uXHB;KDe=P_P(+!gZ8zxR6m=f`dQ6eKxa#mB3^InnD(0G zg|D3%)PCXQy76yM{68NC0Ehu*6$7C=Ii(6s7u( z)=o+Lcu9AsUZU%gG<0cz;Nj!_D@VOr8-8cWufeXD z4NHpNe6Z?R^7YpP@1~Z0`0JdXxZgap)>Hn7Wp_1iLqNz4508QVM+bh`m4Dl5*XIKt zo^Lp<8?~q7>hDxm;U|&pwUSR3yxl+LbnbE4*}jHv?(`?`%ZT0bM^en?ykn)Q6}|c? z#@Sz;&n(?{G~xct^X|W$iR$aS5VG>G8DnGTEp@tnDWdzQADZtZ?5Tb|740qDTe&;Q zPrlhf{72_j@BU}lq2FbYd94FJMG-4=Lnd)&cO^VK5SA&Yx6<~$SE;_2sbnq>a6E@& z1@W4I^(e~xnL={|@S?z)wAXeTo?aAuCbARgO?M~7heh#ngiSzDX}Bq2Cs25uh1GMj z(A?kCK{bb{5K3n5m_*K=|7o=;N8C#w+nN%XZ(;E$AwFrxX0u4{sV5f~2m{6f;g1Sy ztHWGB{UyL|#3Ac@hmP0JIqm;oAj9Te_x#r%P3@IX3fG2bmK{^9eYpJ9I5Af`B@ql` zJA9YTb`+dl^L29hSx(^H{rl~k_Iw?8@mv32R|Hojmpyu}WaC>gu^K(EvvY^y{r&q+ zp6A35rQd(^?xz7)-l=_&zw56rJ#G)C2%1&_7H|M6_9ue{>_9R4Onm%&`zwjR*53at z`EL(Q8RVf2KOQ zbX|?@ZE|1A2Y=6UbRGU4lQBt3cUMDuM`PDy6KRqIv!lZM8c36Zk}INsIME;fKRnTY zwMqAoC*CmJiTkO*L$-PKq_Na@+x9FD9QV6%W#0B9#*Nz~iBpTWt=~3Kt!TcIS~vOo zeG@N~e)`kB4RbvQHqRb^=xlRujsJ&U@we>Ivb(F!oD3hoZe2sr+V^6^PFlY_D(H=j zZv=_zRbhK%n%(!aXQkerZFg*4OPOw8|J1G3;XQfZu032Ax30)j&I@qbyyu%|LtXDA ztf_UX9>vjb_EL?Q_uH-?R*>gBJ~&yHerUnWld<0p3*TE`&_l_~~Zy$fi z+wMml;?B8nNYdjt=QGnL-A(m9NA+#P(2v-C>!`lfGewo}8GdN&*yLY4-RWTdlA()R zJO2CEum8V*alp8USb0}?YVo7huF40mqJWQk>>rJ(R&3rRyqL&&cK*PH*gL*IJuF`y z_VSj@w`zWP{L!VjxQab7rH#gb)}#xU_TJ)5y(wRuuvuhiI%aezbZtEK_&x1y`wB_n zcQsS??{#}CR23Nhx_+y}!a%#)?Z1_J{^5J!L-C^#``WY$tHFMk-@mSJu_^xb#E&D+ zpZMks^;jb3&-Ypx?4Ezki+t|KnV+)`SN{Cc&9}4y(_1Jhq! zefD`(*jK$@?e4ifaSQQYQ_>sn$1MCj#bLLy$)oAI@{6mU?5}pGv)`(SQn%%M+SD8o zY+LlfwbG=F%bsOB4c8rF=PmEvyzBiffEAtr-k_7g3IZKBWHHT!3!g*?nA7gtDHqa+ zl+AS{%Sz;qls(?jJV!w}Xn}z}1;$=3qHOU=D@Usl`npz7R+X z|K&wY=#uqsW`+7sT<#L*_D@|txShW8;Jy#OepjC0b!OhNf-KG-&y3s?IS)I+w@!7YjQAv9#7d;dTgS+qptWy^MEJN>XU`BvfQ9*5FDwqi|L`$xCic%?hlw+G`6 ze|Fzi;5}zL1&=xE@yg|>?~iR7J?*!z-;OwA6D`}?wd4N>1`#z0*A|{4Ztb8Q z-LK!Fa`2-*NTc>be zUGwpp@2?1>yT{wyNEvwZz_QupZ>09lIrpsN_0kt^O;5QY+5fG_h0_Z8*~Q;p{Bu_B z8>5yh&U|$Ha_{q>P2+7iHz)3HN}u|rNp8p0zg=!V{m$OJrCzhn-9ZZ)_I@*P*QzK) zar2{hPh9H#B-U=|VA{g+x7<~ARxZ<~bmV4mx5_I0%e|WhpY@AMzS5oR09grqXUDYf z4zZq*_@XlO*CW$}JjbugALYI5^c$SRz2{`}t)*Gewr;}Zo&tF%Ja&{^XR{uEt;NeBFnJ;S!+DcE$tz%pNx_tR! z(FTtfcYXXxPEgXzXD<${`ZD{c){nnkm3WKu?!%pBsuv=wFVEDaZp|*uv2#6=`^oaP zR7GZY-Qf?8-F)SF>y3r4cE-8J?mawj(Si8~@(X|c(W`I${@U3=R3=o2~1*B{^M z^#{klpgMTqQpiuU*R6eF_jQ3`%7@V@OP@P3{`?pZukBH`>q}YgNo$tAdg+@4c9+(3 z;5W^kL;JFNn?r1CkWMqPZ7^|-Rj$*IC}U7ee4hDf;a8lmW(GoKhUf4Vp78k@AFmgEA;P+>Il~ z`y2{N>yF&yGfhynEzB?%Vf5PJZq_XX^E0Uc%3QA6z}vI=@exHm+_~-I+Zr z!WLd%s>-oDa`&okVB*9tJ_#HOn7wi_dt~W~t)8)o{l~w5Zr&o#MY)s5y`25$SVd#3 zPw5NY`JdH&L&aaO%TD|2uQQ&h6YgwDNdLZ>*t{?G#B274Mt=3zwQV7NANv$+D|=l! zVA#2>#bc;+VgK>I+?`ur8sEFeW!FXSsmyyj4}B{amn4L+PY!iv-FQZ-eO!C@`+#|s zug6@uEB{6D$=J^(_r6B$Yn+?&*CP9q9*avMc7)vp2+aVBODxC!Z{eWGC%M3<)U8|k zPGbNuX=eE>IV64_R=IQ&USt7?Zoi$MUi+{l(Yutixt#~NpEE8Fw)(W1^g&(Eh* z2W50V66Q3qZ}ozTjMwgfzv^x%`!4LV&N(XlmXrdb<+ zH8fAt;;zYtb}&F18Ycf8>#_T0s)?KL=Z^mKd6z_fzP`k^XVzbJ;)m`9X=QVYrk`$l z$Emh)#d}@kv5iBW;;M{-y&QLsw|9RukkPax?oy>bHzA@}I`#bHn)5%unlUAX9e7%* znRD*t9pC+S;+5`|)2=K@3|LxRc{@_DBQZ2NXyk8``;?umo6nYdW(YRSjoa>`-Fsnc zKbZ%TdDid*apnD_22Lqy&^h!!UM2SrO2wxEXEfzH{B|t4(DK0w0oYgogCn=2*>#0n ztx!a1l)$e49c+>g{y4+cb5YGk!A!p-&D6>#5f2bCc0ZUCJ{vvZ+uCD3I~Q*rS z^Yx$BP$xgyFgW4J)m06nFYfW(_4)ORFBON4Ua`JM0}l6IKb4(-t3^es`eXN!{&kPhhe2ChHcj+SU-ew{A7eXzN%DE?>eg1)H3{io zKJasM*n(e*j4w@9Pp^(g)0W>qwBvHu&v)y8K6kg`-M2|Y>#4(bZ_RxPoqId4|MYj& ziLdJp-kp*#Y31e<1CKoyPxtAtDqI-4;F*(4AD(bsyt%y6dd;S7vibMRZ>-n88amXx z`1Vh49UcGS3s>F>UVd$C*tfC!#++F4{D(8vc-7jrcKx2)mHl(o?#Th;9=$!iCjUXh F{{aT6mj?g< literal 0 HcmV?d00001 diff --git a/public/vikon_core/assets/img/background_login.png b/public/vikon_core/assets/img/background_login.png new file mode 100644 index 0000000000000000000000000000000000000000..7365d8384d0f515e5b2c286307a2a55b1082f9d2 GIT binary patch literal 43450 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 EKkZHUYybcN literal 0 HcmV?d00001 diff --git a/public/vikon_core/assets/img/throbber.gif b/public/vikon_core/assets/img/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..74e8450fc12d1885d7441557df3a73eb1b90f7e0 GIT binary patch literal 8874 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 literal 0 HcmV?d00001 diff --git a/public/vikon_core/assets/js/update.js b/public/vikon_core/assets/js/update.js new file mode 100644 index 0000000..4404fa5 --- /dev/null +++ b/public/vikon_core/assets/js/update.js @@ -0,0 +1,2 @@ +/*! For license information please see update.ad32c4d5.js.LICENSE.txt */ +(()=>{"use strict";function e(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,o,c,s=[],i=!0,u=!1;try{if(o=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;i=!1}else for(;!(i=(n=o.call(r)).done)&&(s.push(n.value),s.length!==t);i=!0);}catch(e){u=!0,a=e}finally{try{if(!i&&null!=r.return&&(c=r.return(),Object(c)!==c))return}finally{if(u)throw a}}return s}}(e,t)||r(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function t(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=r(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var a=0,o=function(){};return{s:o,n:function(){return a>=e.length?{done:!0}:{done:!1,value:e[a++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var c,s=!0,i=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return s=e.done,e},e:function(e){i=!0,c=e},f:function(){try{s||null==n.return||n.return()}finally{if(i)throw c}}}}function r(e,t){if(e){if("string"==typeof e)return n(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(e,t):void 0}}function n(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0;--o){var c=this.tryEntries[o],s=c.completion;if("root"===c.tryLoc)return a("end");if(c.tryLoc<=this.prev){var i=n.call(c,"catchLoc"),u=n.call(c,"finallyLoc");if(i&&u){if(this.prev=0;--r){var a=this.tryEntries[r];if(a.tryLoc<=this.prev&&n.call(a,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),D(r),k}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var a=n.arg;D(r)}return a}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,n){return this.delegate={iterator:R(t),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=e),k}},t}function c(e,t,r,n,a,o,c){try{var s=e[o](c),i=s.value}catch(e){return void r(e)}s.done?t(i):Promise.resolve(i).then(n,a)}function s(e){return function(){var t=this,r=arguments;return new Promise((function(n,a){var o=e.apply(t,r);function s(e){c(o,n,a,s,i,"next",e)}function i(e){c(o,n,a,s,i,"throw",e)}s(void 0)}))}}function i(e,t){for(var r=0;rссылке и скорректируйте настройку так, чтобы адрес текущей страницы являлся дочерним по отношению \n к пути, заданному в настройке.');r(new Error(n))}})).fail((function(){return r(new Error("Не удалось проверить настройки безопасности"))}))}))}}],r&&i(t.prototype,r),n&&i(t,n),Object.defineProperty(t,"prototype",{writable:!1}),e}();function F(e,t){var r=!1;Object.values(e).forEach((function(e){if("object"===a(e)&&e.parts){var n=e.parts.find((function(e){return e.id===t.val()}));n&&(r=n.access)}})),r||(t.is(":checked")&&t.attr("checked",!1),t.attr("disabled",!0),t.parent().addClass("disabled"),t.next().prepend('Нет прав'))}if(window.localStorage){var U=new Y,X=new function(){this.setActive=function(){_.addClass("active")},this.setDeactive=function(){_.removeClass("active")},this.setVal=function(e){_.css("width","".concat(e,"%")),_.html("".concat(e,"%"))}};U.init().then(function(){var r=s(o().mark((function r(n){var c,s,i,u,l,f,h,d,y;return o().wrap((function(r){for(;;)switch(r.prev=r.next){case 0:if(!n){r.next=47;break}return r.next=3,Ke();case 3:p=r.sent,(c=$_vikon("#modules-container")).empty(),s=t(Object.values(p).entries()),r.prev=7,s.s();case 9:if((i=s.n()).done){r.next=19;break}if(u=e(i.value,2),l=u[0],!("object"===a(f=u[1])&&f.id&&f.name&&f.parts)){r.next=17;break}return r.next=14,Xe(f.id);case 14:h=r.sent,d=V(f,h,l),c.append(d);case 17:r.next=9;break;case 19:r.next=24;break;case 21:r.prev=21,r.t0=r.catch(7),s.e(r.t0);case 24:return r.prev=24,s.f(),r.finish(24);case 27:return $_vikon('input[name="part"]').each((function(){F(p,$_vikon(this))})),$_vikon(".select-all-checkbox").each((function(){var e=$_vikon(this).data("module-id"),t=$_vikon(this).closest(".module-block").find('input[name="part"]:not(:disabled)'),r=t.length>0&&t.length===t.filter(":checked").length;$_vikon(this).prop("checked",r),$_vikon(this).on("change",(function(){M(e)}))})),11176==N?$_vikon('input[name="part"]').on("change",(function(){var e=$_vikon(this).closest(".module-block"),t=e.find(".select-all-checkbox");if(t.length){var r=e.find('input[name="part"]:not(:disabled)'),n=r.length>0&&r.length===r.filter(":checked").length;t.prop("checked",n)}})):$_vikon('input[name="part"]').each((function(){$_vikon(this).attr("disabled",!0)})),p.additional_access_flags&&-1!==p.additional_access_flags.indexOf("admin_mode")&&$_vikon("#admin-mode-panel").removeClass("d-none"),p.additional_access_flags&&-1!==p.additional_access_flags.indexOf("no_update_abitur")&&$_vikon("#module-2").remove(),p.additional_access_flags&&-1!==p.additional_access_flags.indexOf("no_update_vsoko")&&$_vikon("#module-6").remove(),p.additional_access_flags&&-1!==p.additional_access_flags.indexOf("no_update_corruption_part")&&$_vikon("#corruption").closest("li").remove(),p.additional_access_flags&&-1!==p.additional_access_flags.indexOf("no_update_antiterrorism_part")&&$_vikon("#antiterrorism").closest("li").remove(),p.additional_access_flags&&-1!==p.additional_access_flags.indexOf("no_update_vsoko_feedback_part")&&$_vikon("#feedback").closest("li").remove(),k.remove(),m.show(),E.show(),r.next=41,B();case 41:return r.next=43,Fe();case 43:null===(y=r.sent)||C!==y?v.removeClass("bg-warning").addClass("bg-success").html(y):(v.removeClass("bg-warning").addClass("bg-secondary"),v.html("обновления отсутствуют")),r.next=49;break;case 47:k.remove(),w.show();case 49:case"end":return r.stop()}}),r,null,[[7,21,24,27]])})));return function(e){return r.apply(this,arguments)}}()).catch((function(e){h.html(e.message).show()}))}else k.remove(),h.html("Объект localStorage не поддерживается данным браузером. Пожалуйста, воспользуйтесь другим Internet-браузером.").show();function M(e){var t=$_vikon("#select-all-"+e),r=t.closest(".module-block"),n=r.find('input[name="part"]:not(:disabled)');t.is(":checked")?n.prop("checked",!0):r.find('input[name="part"]').prop("checked",!1)}function V(e,t,r){var n=$_vikon("

    ",{class:"list-unstyled module-block",id:"module-".concat(e.id)}),a=t?''.concat(t,""):"",o=$_vikon("
  • ").html("".concat(e.name).concat(a,""));if(n.append(o),1!==r){var c=$_vikon("
  • "),s=$_vikon("
    ",{class:"checkbox"}),i=$_vikon("",{type:"checkbox",class:"select-all-checkbox",id:"select-all-"+e.id,"data-module-id":e.id,disabled:11176!=N}),u=$_vikon("
  • "),r=$_vikon("
    ",{class:"checkbox"}),a=$_vikon("",{type:"checkbox",name:"part",id:e.id,value:e.id,checked:e.access}),o=$_vikon("
    + + diff --git a/public/vikon_core/update/is_writable.php b/public/vikon_core/update/is_writable.php new file mode 100644 index 0000000..0e606cb --- /dev/null +++ b/public/vikon_core/update/is_writable.php @@ -0,0 +1,31 @@ +'; + } + } else if (!is_writable($dir)) { + $message .= 'Отсутствуют права на запись: "' . $dir . '"
    '; + } + return $message; +} + +$messageSveden = ''; +$root = dirname($selfDir); +if (file_exists($root)) { + $messageSveden = isWritableR($root); +} + +if ($messageSveden) { + echo '

    ' . $messageSveden . '

    '; +} diff --git a/public/vikon_core/update/make_executor.php b/public/vikon_core/update/make_executor.php new file mode 100644 index 0000000..dcc9568 --- /dev/null +++ b/public/vikon_core/update/make_executor.php @@ -0,0 +1,50 @@ +curlHasError) { + throw new RuntimeException('CURL ' . $hasAccess->curlErrorTxt); + } + + if ($hasAccess->code !== 200) { + $err = 'Не удается скачать файл с обновлениями. ' . (!empty($hasAccess->responseBody->message) + ? $hasAccess->responseBody->message + : 'Неизвестная ошибка'); + sendErrorResponse($hasAccess->code, $err); + } + + if ($hasAccess->responseBody->success) { + $vikonRootPath = Path::getCoreRootPath(); + $executorPath = Path::join($vikonRootPath, Path::$executorFile); + + if (!Filesystem::remove($executorPath, false)) { + sendErrorResponse(500, 'Ошибка при генерации ядра. Не удалось удалить устаревший исполняемый скрипт: ' . $executorPath); + } + + $srcForExecutorPath = Path::getSrcForExecutorPath(); + $executorCode = file_get_contents($srcForExecutorPath); + if (!$executorCode || !Filesystem::safeMkfile($executorPath, 0755, $executorCode)) { + sendErrorResponse(500, 'Ошибка при генерации ядра. Не удалось создать исполняемый скрипт: ' . $executorPath); + } + sendSuccessResponse(''); + } +} catch (Exception $ex) { + sendErrorResponse(500, $ex->getMessage()); +} +if ($dlHandler) { + fclose($dlHandler); +} diff --git a/public/vikon_core/update/purge.php b/public/vikon_core/update/purge.php new file mode 100644 index 0000000..8a71179 --- /dev/null +++ b/public/vikon_core/update/purge.php @@ -0,0 +1,69 @@ +curlHasError) { + sendErrorResponse(500, 'CURL ' . $res->curlErrorTxt); +} +if ($res->code !== 200) { + $err = 'Ошибка проверки подлинности токена. ' + . (!empty($zipCore->responseBody->message) ? $zipCore->responseBody->message : 'Неизвестная ошибка'); + sendErrorResponse($res->code, $err); +} + +$isAccessRemoveOldScriptsUpdate = 0; +if (isset($_POST['is_access_remove_old_scripts_update']) && in_array((int) $_POST['is_access_remove_old_scripts_update'], array(0, 1))) { + $isAccessRemoveOldScriptsUpdate = (int) $_POST['is_access_remove_old_scripts_update']; +} + +Path::init($modulesByPathDeploy); +$vikonRootPath = Path::getCoreRootPath(); + +//remove executor +$executorPath = Path::join($vikonRootPath, Path::$executorFile); +if (!Filesystem::remove($executorPath, false)) { + sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . $executorPath); +} + +//fail +$vikonCoreLatestPath = Path::join($vikonRootPath, 'vikon_core-latest'); +if (!Filesystem::remove($vikonCoreLatestPath, true)) { + sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . $vikonCoreLatestPath); +} + +//todo new_core_after +//Удаляем старые скрипты в папке sveden/update +if ($isAccessRemoveOldScriptsUpdate) { + $svedenRoot = Path::getModuleRootPath(SVEDEN); + if (!file_exists($svedenRoot)) { + sendSuccessResponse('Временные файлы успешно удалены.'); + } + $svedenFuncPath = Path::join($svedenRoot, 'update'); + if (!file_exists($svedenFuncPath)) { + sendSuccessResponse('Временные файлы успешно удалены.'); + } + $entriesFunc = Filesystem::safeScandir($svedenFuncPath); + if (!$entriesFunc) { + sendSuccessResponse('Временные файлы успешно удалены.'); + } + $excludeEntries = array('index.php'); + foreach ($entriesFunc as $entry) { + if (in_array($entry, $excludeEntries)) { + continue; + } + if (!Filesystem::remove(Path::join($svedenFuncPath, $entry), true, SVEDEN)) { + sendErrorResponse(500, 'Ошибка при очистке ядра. Не удалось удалить исполняемый файл:' . Path::join($svedenFuncPath, $entry)); + } + } +} +sendSuccessResponse('Временные файлы успешно удалены.'); diff --git a/public/vikon_core/update/refresh_access_token.php b/public/vikon_core/update/refresh_access_token.php new file mode 100644 index 0000000..cec0cb2 --- /dev/null +++ b/public/vikon_core/update/refresh_access_token.php @@ -0,0 +1,50 @@ + $refreshToken, + 'client_id' => $clientId, + 'client_secret' => $clientSecret, + 'grant_type' => 'refresh_token', + ), $headers); + + if ($data->curlHasError) { + $res['message'] = 'Не удалось соединиться с сервером.' . $data->curlErrorTxt; + setResponseCode(500); + } else { + if (isset($data->responseBody->access_token)) { + $res['access_token'] = $data->responseBody->access_token; + $res['refresh_token'] = $data->responseBody->refresh_token; + $res['success'] = true; + } else { + $message = ''; + if (isset($data->responseBody->message)) { + $message = $data->responseBody->message; + } else { + $message = 'Ошибка при получении токена.'; + } + $res['message'] = $message; + setResponseCode($data->code); + } + } + +} catch (Exception $e) { + $res['message'] = 'Ошибка при обновлении ключа. ' . $e->getMessage(); + setResponseCode(500); +} + +loadHeaders(); +echo json_encode($res); + diff --git a/public/vikon_core/update/request_generate_part.php b/public/vikon_core/update/request_generate_part.php new file mode 100644 index 0000000..4393532 --- /dev/null +++ b/public/vikon_core/update/request_generate_part.php @@ -0,0 +1,44 @@ + $part, 'is_new_core' => true); + $response = remoteRequest($apiDomen . 'pull_updates/generatePartByNewCoreJson', true, $post, $headers); + if (!$response->curlHasError) { + if (200 === $response->code) { + $resultBody = array( + 'success' => true, + 'operation_identity' => $response->responseBody->operation_identity, + 'ttl' => $response->responseBody->ttl, + 'forward_code' => 200, + ); + } else { + $err = !empty($response->responseBody->message) ? $response->responseBody->message : 'Неизвестная ошибка'; + sendErrorResponse($response->code, $err); + } + } else { + throw new RuntimeException('CURL ' . $response->curlErrorTxt); + } +} catch (Exception $ex) { + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/request_new_file.php b/public/vikon_core/update/request_new_file.php new file mode 100644 index 0000000..1f8aae2 --- /dev/null +++ b/public/vikon_core/update/request_new_file.php @@ -0,0 +1,120 @@ +curlHasError) { + throw new RuntimeException('CURL ' . $response->curlErrorTxt); + } + + if ( + $response->code !== 200 + || !property_exists($response->responseBody, 'file_name') + || !property_exists($response->responseBody, 'identity') + || !property_exists($response->responseBody, 'dir_name') + ) { + $msg = 'Не удалось получить информацию о файле, котрый требуется загрузить ' + . tryExtractFmErrorMessage($response, '. '); + sendErrorResponse($response->code, $msg); + } + + if ($response->responseBody->file_name === null && $response->responseBody->identity === null) { + $resultBody = array( + 'success' => true, + 'forward_code' => 200, + 'done' => true, + ); + loadHeaders(); + setResponseCode(200); + echo json_encode($resultBody); + die(); + } + + $fileIdentity = $response->responseBody->identity; + $filename = $response->responseBody->file_name; + $directory = $response->responseBody->dir_name; + + if (!Filesystem::ensureValidDirectoryAndFileName($directory, $filename)) { + throw new RuntimeException('Некорректные параметры сохранения: недопустимое имя директории или файла.'); + } + + $headers = array('Accept-Encoding: zip, gzip', 'Authorization: Bearer ' . $token); + $binFile = remoteRequest( + $filemanagerApiDomen . 'sync/downloadFileBinary?identity=' . $fileIdentity, + false, + false, + $headers + ); + if ($binFile->curlHasError) { + throw new RuntimeException('CURL ' . $binFile->curlErrorTxt); + } + + if ($binFile->code !== 200) { + $binFile->responseBody = json_decode($binFile->responseBody); + $message = 'Не удается скачать файл ' . $filename . tryExtractFmErrorMessage($binFile, '. '); + sendErrorResponse($binFile->code, $message); + } + + $fsPathDir = Path::getFsPathByModule($moduleId); + if ($directory !== null) { + $fsPathDir = Path::join($fsPathDir, $directory); + } + + if (!Filesystem::safeMkdir($fsPathDir, 0775, $moduleId)) { + throw new RuntimeException('Не удалось создать папку "' . $fsPathDir . '" на вашем сервере'); + } + + $fsFilePath = Path::join($fsPathDir, $filename); + $dlHandler = fopen($fsFilePath, 'w'); + if ($dlHandler == false || !fwrite($dlHandler, $binFile->responseBody)) { + throw new RuntimeException('Не удается записать файл ' . $fsFilePath . ' на диск', 500); + } + + $headers = array('Authorization: Bearer ' . $token); + $response = remoteRequest( + $filemanagerApiDomen . 'sync/markNewFileAsLoaded?identity=' . $fileIdentity . '&moduleId=' . $moduleId, + true, + false, + $headers + ); + if ($response->code !== 200) { + $message = 'Не удалось пометить файл' . $filename . ' как обновленный' + . tryExtractFmErrorMessage($response, '. '); + sendErrorResponse($response->code, $message); + } + + $resultBody = array( + 'success' => true, + 'forward_code' => 200, + 'message' => 'Файл ' . $filename . ' загружен', + 'done' => false, + ); +} catch (Exception $ex) { + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +if ($dlHandler) { + fclose($dlHandler); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/request_sync_file.php b/public/vikon_core/update/request_sync_file.php new file mode 100644 index 0000000..ba9d85c --- /dev/null +++ b/public/vikon_core/update/request_sync_file.php @@ -0,0 +1,131 @@ +curlHasError) { + throw new RuntimeException('CURL ' . $response->curlErrorTxt); + } + + if ( + $response->code !== 200 + || !property_exists($response->responseBody, 'file_name') + || !property_exists($response->responseBody, 'identity') + || !property_exists($response->responseBody, 'dir_name') + ) { + $resultBody = array( + 'success' => false, + 'forward_code' => $response->code == 200 ? 500 : $response->code, + 'message' => (int) $response->code === 404 + ? 'Не удалось получить информацию об одном из синхронизируемых файлов. Файл был удален из системы после запуска процесса синхронизации. Перезапустите синхронизацию файлов.' + : 'Не удалось получить информацию о файле, котрый требуется загрузить ' . tryExtractFmErrorMessage($response, '. '), + 'debug_identity' => $fileIdentity, + ); + loadHeaders(); + setResponseCode(200); + echo json_encode($resultBody); + die(); + } + + $identity = $response->responseBody->identity; + $filename = $response->responseBody->file_name; + $directory = $response->responseBody->dir_name; + + if (!Filesystem::ensureValidDirectoryAndFileName($directory, $filename)) { + throw new RuntimeException('Некорректные параметры сохранения: недопустимое имя директории или файла.'); + } + + $headers = array('Accept-Encoding: zip, gzip', 'Authorization: Bearer ' . $token); + $bin = remoteRequest( + $filemanagerApiDomen . 'sync/downloadFileBinaryForSync?identity=' . $identity . '&moduleId=' . $moduleId, + false, + false, + $headers + ); + if ($bin->curlHasError) { + throw new RuntimeException('CURL ' . $bin->curlErrorTxt); + } + + if ($bin->code !== 200) { + $bin->responseBody = json_decode($bin->responseBody); + $resultBody = array( + 'success' => false, + 'forward_code' => $bin->code, + 'message' => 'Не удается скачать файл ' . $filename . tryExtractFmErrorMessage($bin, '. '), + 'debug_identity' => $fileIdentity, + ); + loadHeaders(); + setResponseCode(200); + echo json_encode($resultBody); + die(); + } + + $fsPathDir = Path::getFsPathByModule($moduleId); + if (!$fsPathDir) { + throw new RuntimeException('Неизвестная ошибка'); + } + + if ($directory !== null) { + $fsPathDir = Path::join($fsPathDir, $directory); + } + + if (!Filesystem::safeMkdir($fsPathDir, 0775, $moduleId)) { + throw new RuntimeException('Не удалось создать папку "' . $fsPathDir . '" на вашем сервере'); + } + + $filePath = Path::join($fsPathDir, $filename); + + $dlHandler = fopen($filePath, 'w'); + if ($dlHandler === false) { + throw new RuntimeException('Не удается открыть файл для записи: ' . $filePath); + } + + if (fwrite($dlHandler, $bin->responseBody) === false) { + throw new RuntimeException('Не удается записать файл на диск: ' . $filePath); + } + + $resultBody = array( + 'success' => true, + 'forward_code' => 200, + 'message' => 'Файл ' . $filename . ' загружен', + ); +} catch (Exception $ex) { + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +if ($dlHandler) { + fclose($dlHandler); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/result_check_generate_part.php b/public/vikon_core/update/result_check_generate_part.php new file mode 100644 index 0000000..806fd5c --- /dev/null +++ b/public/vikon_core/update/result_check_generate_part.php @@ -0,0 +1,57 @@ +curlHasError) { + if ($response->code === 200) { + $resultBody = array( + 'success' => true, + 'forward_code' => 200, + ); + } else { + $resultBody = array( + 'success' => false, + 'forward_code' => $response->code, + 'message' => !empty($response->responseBody->message ) ? $response->responseBody->message : 'Неизвестная ошибка' + ); + } + } else { + throw new RuntimeException('CURL ' . $response->curlErrorTxt); + } +} catch (Exception $ex) { + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/result_download_part.php b/public/vikon_core/update/result_download_part.php new file mode 100644 index 0000000..9f95502 --- /dev/null +++ b/public/vikon_core/update/result_download_part.php @@ -0,0 +1,229 @@ +curlHasError) { + if ($response->code === 200) { + $curModuleId = 0; + foreach ($allowedFoldersInCoreByModule as $moduleId => $parts) { + if (is_array($parts) && in_array($part, $parts)) { + $curModuleId = $moduleId; + break; + } + } + + $funcPath = Path::getFunctionalPath(); + $filenameZip = Path::join($funcPath, $operationIdentity . '.zip'); + + if (!Filesystem::removeZip($filenameZip, true)) { + $err = 'Ошибка при распаковке раздела: "' . $part . '".' + . ' Базовый архив раздела уже существует, недостаточно прав для его удаления.'; + sendErrorResponse(500, $err); + } + + $dlHandler = fopen($filenameZip, 'w'); + if (!fwrite($dlHandler, $response->responseBody)) { + $err = 'Ошибка при распаковке раздела: "' . $part . '".' + . ' Не удалось записать архив. Проверьте права доступа и свободное место.'; + sendErrorResponse(500, $err); + } + + $unpackPath = Path::join($funcPath, $part.'_part-latest'); + if (!Filesystem::remove($unpackPath, true)) { + $err = 'Ошибка при распаковке раздела: "' . $part . '".' + . ' Временная директория уже существует и не может быть удалена.'; + sendErrorResponse(500, $err); + } + + if (!unpackZip($filenameZip, $unpackPath)) { + $err = 'Ошибка при распаковке раздела: ' . $part . '.' + . ' Проверьте права доступа и свободное место.'; + sendErrorResponse(500, $err); + } + Filesystem::removeZip($filenameZip, false); + + $errRepeir = 'Ошибка при синхронизации раздела. Не удалось восстановить часть: ' . $part; + $errSync = 'Ошибка при синхронизации раздела. Не удалось синхронизировать часть: ' . $part; + + $rootModuleCore = Path::getModuleRootPath($curModuleId); + $pathCurFolderPart = Path::join($rootModuleCore, $part); + $excludedEntries = array(); + if ('abitur' !== $part) { + $excludedEntries = $allowedFoldersInCoreByModule[$curModuleId]; + $pathCurFolderPart = Path::join($rootModuleCore, $part); + if (file_exists($pathCurFolderPart)) { + $pathPartForSync = Path::join($unpackPath, $part); + $pathPartForSyncPostfixNew = Path::join($rootModuleCore, $part.Path::$n_pstfx); + + if (!Filesystem::remove($pathPartForSyncPostfixNew, true, $curModuleId)) { + if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) { + sendErrorResponse(500, $errRepeir); + } + } + if (!Filesystem::replaceWithRename($pathPartForSync, $pathPartForSyncPostfixNew, $curModuleId)) { + if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) { + sendErrorResponse(500, $errRepeir); + } + sendErrorResponse(500, $errSync); + } + + $pathCurFolderPartOldPostfix = Path::join($rootModuleCore, $part.Path::$o_pstfx); + if (!Filesystem::remove($pathCurFolderPartOldPostfix, true, $curModuleId)) { + if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) { + sendErrorResponse(500, $errRepeir); + } + sendErrorResponse(500, $errSync); + } + if (!Filesystem::replaceWithRename($pathCurFolderPart, $pathCurFolderPartOldPostfix, $curModuleId)) { + if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) { + sendErrorResponse(500, $errRepeir); + } + sendErrorResponse(500, $errSync); + } + + if (!Filesystem::replaceWithRename($pathPartForSyncPostfixNew, $pathCurFolderPart, $curModuleId)) { + if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) { + sendErrorResponse(500, $errRepeir); + } + sendErrorResponse(500, $errSync); + } + } else { + $pathPartForSync = Path::join($unpackPath, $part); + if (!Filesystem::replaceWithRename($pathPartForSync, $pathCurFolderPart, $curModuleId)) { + if (!Filesystem::restoreUnitCoreAfterFail($rootModuleCore, array($part), $curModuleId)) { + sendErrorResponse(500, $errRepeir); + } + sendErrorResponse(500, $errSync); + } + } + } else { + $pathCurFolderPart = $rootModuleCore; + $entrySyncFail = null; + $isRestoreFail = false; + $entriesToSync = Filesystem::safeScandir(Path::join($unpackPath, $part)); + $excludedEntries = array_merge($entriesToSync, array('files', '.htaccess'));//todo подумать как от этого костыля отказаться + foreach ($entriesToSync as $entryName) { + $currentEntryPath = Path::join($pathCurFolderPart, $entryName); + $newEntryPath = Path::join($unpackPath, $part, $entryName); + $isFile = is_file($newEntryPath); + + if (file_exists($currentEntryPath)) { + $newEntryPathWithNewPostfix = Path::join($pathCurFolderPart, $entryName.Path::$n_pstfx); + // try del + if (!Filesystem::remove($newEntryPathWithNewPostfix, true, $curModuleId)) { + $failedEntryName = $entryName; + break; + } + // try replace + $renameSuccess = !$isFile + ? Filesystem::replaceWithRename($newEntryPath, $newEntryPathWithNewPostfix, $curModuleId) + : Filesystem::safeRenameFile($newEntryPath, $newEntryPathWithNewPostfix, $curModuleId); + if (!$renameSuccess) { + $failedEntryName = $entryName; + break; + } + $currentEntryPathWithOldPostfix = Path::join($pathCurFolderPart, $entryName.Path::$o_pstfx); + // try del + if (!Filesystem::remove($currentEntryPathWithOldPostfix, true, $curModuleId)) { + $failedEntryName = $entryName; + break; + } + + // try replace + $renameSuccess = !$isFile + ? Filesystem::replaceWithRename($currentEntryPath, $currentEntryPathWithOldPostfix, $curModuleId) + : Filesystem::safeRenameFile($currentEntryPath, $currentEntryPathWithOldPostfix, $curModuleId); + if (!$renameSuccess) { + $failedEntryName = $entryName; + break; + } + + // try replace + $renameSuccess = !$isFile + ? Filesystem::replaceWithRename($newEntryPathWithNewPostfix, $currentEntryPath, $curModuleId) + : Filesystem::safeRenameFile($newEntryPathWithNewPostfix, $currentEntryPath, $curModuleId); + if (!$renameSuccess) { + $failedEntryName = $entryName; + break; + } + } else { + // try replace + $renameSuccess = !$isFile + ? Filesystem::replaceWithRename($newEntryPath, $currentEntryPath, $curModuleId) + : Filesystem::safeRenameFile($newEntryPath, $currentEntryPath, $curModuleId); + if (!$renameSuccess) { + $failedEntryName = $entryName; + break; + } + } + } + } + + Filesystem::remove($unpackPath, true); + + $successOrPath = Filesystem::cleanUnitCore($rootModuleCore, $excludedEntries, $curModuleId); + if (is_string($successOrPath)) { + $err = 'Ошибка проверки целостности части. Не удалось удалить папку: ' . $successOrPath; + sendErrorResponse(500, $err); + } + if (!$successOrPath) { + $err = 'Ошибка проверки целостности части. Нет доступа к корневой папке части.'; + sendErrorResponse(500, $err); + } + $resultBody = array('success' => true, 'forward_code' => 200, 'message' => 'Раздел ' . $part . ' успешно обновлен.'); + } else { + $response->responseBody = json_decode($response->responseBody); + + $resultBody = array( + 'success' => false, + 'forward_code' => $response->code, + 'message' => !empty($response->responseBody->message ) ? $response->responseBody->message : 'неизвестная ошибка' + ); + } + } else { + throw new RuntimeException('CURL ' . $response->curlErrorTxt); + } +} catch (Exception $ex) { + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +if ($dlHandler != null) { + fclose($dlHandler); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/src_executor.php b/public/vikon_core/update/src_executor.php new file mode 100644 index 0000000..ed00d4f --- /dev/null +++ b/public/vikon_core/update/src_executor.php @@ -0,0 +1,132 @@ +curlHasError) { + throw new RuntimeException('CURL ' . $zipCore->curlErrorTxt); + } + + if ($zipCore->code !== 200) { + $zipCore->responseBody = json_decode($zipCore->responseBody); + + $err = 'Не удается скачать файл с обновлениями. ' . (!empty($zipCore->responseBody->message) + ? $zipCore->responseBody->message + : 'Неизвестная ошибка'); + sendErrorResponse($zipCore->code, $err); + } + + $vikonFuncPath = Path::getCoreRootPath(); + $vikonZipCorePath = Path::join($vikonFuncPath, 'vikon_core-latest.zip'); + + if (!Filesystem::removeZip($vikonZipCorePath, true)) { + $err = 'Ошибка при распаковке ядра. Архив уже существует. Недостаточно прав для его удаления'; + sendErrorResponse(500, $err); + } + + $dlHandler = fopen($vikonZipCorePath, 'w'); + if (!fwrite($dlHandler, $zipCore->responseBody)) { + $err = 'Ошибка при распаковке ядра модуля. Не удалось записать архив. Проверьте права доступа и свободное место.'; + sendErrorResponse(500, $err); + } + + if ($dlHandler) { + fclose($dlHandler); + } + + $vikonUnpackNewCorePath = Path::join($vikonFuncPath, 'vikon_core-latest'); + + if (!Filesystem::remove($vikonUnpackNewCorePath, true)) { + $err = 'Ошибка при распаковке ядра. Временная директория уже существует и не может быть удалена.'; + sendErrorResponse(500, $err); + } + + $unpackResult = unpackZip($vikonZipCorePath, $vikonUnpackNewCorePath); + if (!$unpackResult['success']) { + sendErrorResponse(500, 'Ошибка при распаковке ядра. Проверьте права доступа и свободное место.'); + } + Filesystem::removeZip($vikonZipCorePath, false); + + $vikonRootPath = Path::getCoreRootPath(); + + $pathToFoldersNewCore = Path::join($vikonUnpackNewCorePath, Path::$vikonCoreFolder); + $nameFoldersForSync = Filesystem::safeScandir($pathToFoldersNewCore); + $isRestoreFail = false; + $folderSyncFail = null; + foreach ($nameFoldersForSync as $nameFolderSync) { + $curFolder = Path::join($vikonRootPath, $nameFolderSync); + $pathToNewFolder = Path::join($vikonUnpackNewCorePath, Path::$vikonCoreFolder, $nameFolderSync); + + if (file_exists($curFolder)) { + $pathToNewFolderPostfix = Path::join($vikonRootPath, $nameFolderSync . Path::$n_pstfx); + // try del vikon_core/assets_new + if (!Filesystem::remove($pathToNewFolderPostfix, true)) { + $folderSyncFail = $nameFolderSync; + break; + } + // try replace vikon_core/vikon_core-latest/vikon_core/assets -> vikon_core/assets_new + if (!Filesystem::replaceWithRename($pathToNewFolder, $pathToNewFolderPostfix)) { + $folderSyncFail = $nameFolderSync; + break; + } + + $pathToOldFolderPostfix = Path::join($vikonRootPath, $nameFolderSync . Path::$o_pstfx); + // try del vikon_core/assets_old + if (!Filesystem::remove($pathToOldFolderPostfix, true)) { + $folderSyncFail = $nameFolderSync; + break; + } + // try replace vikon_core/assets -> vikon_core/assets_old + if (!Filesystem::replaceWithRename($curFolder, $pathToOldFolderPostfix)) { + $folderSyncFail = $nameFolderSync; + break; + } + + // vikon_core/assets_new -> vikon_core/assets + if (!Filesystem::replaceWithRename($pathToNewFolderPostfix, $curFolder)) { + $folderSyncFail = $nameFolderSync; + break; + } + } else { + // try replace vikon_core/vikon_core-latest/vikon_core/assets -> vikon_core/assets + if (!Filesystem::replaceWithRename($pathToNewFolder, $curFolder)) { + $folderSyncFail = $nameFolderSync; + break; + } + } + } + //синхронизированные папки + временная папка с версиями + $allFoldersNeedCore = array_merge($nameFoldersForSync, array('tmp')); + if ($folderSyncFail !== null) { + if (!Filesystem::restoreUnitCoreAfterFail($vikonRootPath, $allFoldersNeedCore)) { + sendErrorResponse(500, 'Ошибка при синхронизации ядра. Не удалось восстановить ядро после ошибки.'); + } else { + sendErrorResponse(500, 'Ошибка при синхронизации ядра. Не удалось синхронизировать папку: ' . $folderSyncFail); + } + } + + $successOrPath = Filesystem::cleanUnitCore($vikonRootPath, $allFoldersNeedCore); + if (is_string($successOrPath)) { + sendErrorResponse(500, 'Ошибка проверки целостности ядра. Не удалось удалить папку: ' . $successOrPath); + } + if (!$successOrPath) { + sendErrorResponse(500, 'Ошибка проверки целостности ядра. Нет доступа к корневой папке ядра.'); + } +} catch (Exception $ex) { + sendErrorResponse(500, $ex->getMessage()); +} + +sendSuccessResponse('Архив с базовыми обновлениями успешно загружен.'); diff --git a/public/vikon_core/update/start_sync_files.php b/public/vikon_core/update/start_sync_files.php new file mode 100644 index 0000000..02594b0 --- /dev/null +++ b/public/vikon_core/update/start_sync_files.php @@ -0,0 +1,74 @@ +code !== 200) { + $msg = 'Не удалось инициировать процедуру синхронизации файлов' . tryExtractFmErrorMessage($response, '. '); + sendErrorResponse($response->code, $msg); + } + + if (!property_exists($response->responseBody, 'directories') || !is_array($response->responseBody->directories)) { + throw new RuntimeException('Невалидный формат ответа при запросе используемых директорий'); + } + + $directories = $response->responseBody->directories; + $fsRootPath = Path::getFsPathByModule($moduleId); + if (!$fsRootPath) { + throw new RuntimeException('Неизвестная ошибка'); + } + + $dirObjects = Filesystem::safeScandir($fsRootPath); + if (false === $dirObjects) { + $msg = 'Не удалось просканировать папку: ' . $fsRootPath; + sendErrorResponse(500, $msg); + } + + $flippedKnownDirectories = array_flip($directories); + foreach ($dirObjects as $objectName) { + $objectPath = Path::join($fsRootPath, $objectName); + if ( + !array_key_exists($objectName, $flippedKnownDirectories) + && is_dir($objectPath) + ) { + if (is_link($fsRootPath)) { + throw new RuntimeException( + 'В синхронизируемый директории находится ссылка' + . $objectPath + . ' , которая не может быть безопасно удалена' + ); + } + Filesystem::remove($objectPath, true, $moduleId); + } + } + + $resultBody = array( + 'success' => true, + 'forward_code' => 200, + 'directories' => $directories, + ); +} catch (Exception $ex) { + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/status_generate_part.php b/public/vikon_core/update/status_generate_part.php new file mode 100644 index 0000000..a5b1197 --- /dev/null +++ b/public/vikon_core/update/status_generate_part.php @@ -0,0 +1,50 @@ +curlHasError) { + if (200 === $response->code) { + $resultBody = array( + 'success' => true, + 'status' => $response->responseBody->status, + 'forward_code' => 200, + ); + } else { + $resultBody = array( + 'success' => false, + 'forward_code' => $response->code, + 'message' => !empty($response->responseBody->message ) ? $response->responseBody->message : 'неизвестная ошибка' + ); + } + } else { + throw new RuntimeException('CURL ' . $response->curlErrorTxt); + } +} catch (Exception $ex) { + setResponseCode(!empty($response->code) ? $response->code : 500); + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/sync_root_dir.php b/public/vikon_core/update/sync_root_dir.php new file mode 100644 index 0000000..a073308 --- /dev/null +++ b/public/vikon_core/update/sync_root_dir.php @@ -0,0 +1,109 @@ +curlHasError) { + throw new RuntimeException('CURL ' . $response->curlErrorTxt); + } + + if ( + $response->code !== 200 + || !property_exists($response->responseBody, 'files') + || !is_array($response->responseBody->files) + ) { + $msg = 'Не удалось получить список файлов с файлового сервера' + . tryExtractFmErrorMessage($response, '. '); + sendErrorResponse($response->code, $msg); + } + $filesByNamesFromFm = array(); + foreach ($response->responseBody->files as $row) { + $filesByNamesFromFm[(string) $row->n] = $row->i; + } + $response = null; + + if (!Filesystem::safeMkdir($fsDirPath, 0775, $moduleId)) { + throw new RuntimeException('Не удалось создать папку "' . $fsDirPath . '" на вашем сервере'); + } + $items = Filesystem::safeScandir($fsDirPath); + if (false === $items) { + $msg = 'Не удалось просканировать существующие файлы'; + sendErrorResponse(500, $msg); + } + + $existingItemsByNames = array(); + foreach ($items as $fName) { + $existingItemsByNames[$fName] = null; + } + + $knownSubDirsByNames = array_flip($knownSubDirs); + foreach ($existingItemsByNames as $dirItem => $_) { + $fsItemPath = Path::join($fsDirPath, $dirItem); + if ((array_key_exists($dirItem, $knownSubDirsByNames) && is_dir($fsItemPath))) { + unset($existingItemsByNames[$dirItem]); + continue; + } + + if (!array_key_exists((string) $dirItem, $filesByNamesFromFm)) { + //удаляем только файлы, ненужные папки были удалены в start_sync_files + if (is_file($fsItemPath)) { + unlink($fsItemPath); + } + } else { + if (!filesize($fsItemPath)) { + unset($existingItemsByNames[$dirItem]); + } + } + } + + $filesForSync = array(); + foreach ($filesByNamesFromFm as $fileName => $identity) { + if (!array_key_exists($fileName, $existingItemsByNames)) { + $filesForSync[] = $identity; + } + } + + $resultBody = array('success' => true, 'forward_code' => 200, 'files' => $filesForSync); +} catch (Exception $ex) { + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/sync_sub_dir.php b/public/vikon_core/update/sync_sub_dir.php new file mode 100644 index 0000000..3efe40a --- /dev/null +++ b/public/vikon_core/update/sync_sub_dir.php @@ -0,0 +1,100 @@ +curlHasError) { + throw new RuntimeException('CURL ' . $response->curlErrorTxt); + } + if ( + $response->code !== 200 + || !property_exists($response->responseBody, 'files') + || !is_array($response->responseBody->files) + ) { + $message = 'Не удалось получить список файлов с файлового сервера' + . tryExtractFmErrorMessage($response, '. '); + sendErrorResponse($response->code, $message); + } + + $filesByNamesFromFm = array(); + foreach ($response->responseBody->files as $row) { + $filesByNamesFromFm[(string) $row->n] = $row->i; + } + $response = null; + + $fsDirPath = Path::getFsPathByModule($moduleId); + if (!$fsDirPath) { + throw new RuntimeException('Не удалось определить модуль'); + } + + $dirPath = Path::join($fsDirPath, $dir); + if (!Filesystem::safeMkdir($dirPath, 0775, $moduleId)) { + throw new RuntimeException('Не удалось создать папку "' . $dirPath . '" на вашем сервере'); + } + + $items = Filesystem::safeScandir($dirPath); + if (false === $items) { + $msg = 'Не удалось просканировать существующие файлы'; + sendErrorResponse(500, $msg); + } + + $existingItemsByNames = array(); + foreach ($items as $fName) { + $existingItemsByNames[$fName] = null; + } + + foreach ($existingItemsByNames as $subDirItem => $_) { + $filePath = Path::join($dirPath, $subDirItem); + if (!array_key_exists((string) $subDirItem, $filesByNamesFromFm)) { + if (is_dir($filePath)) { + Filesystem::remove($filePath, true); + } else { + unlink($filePath); + } + } else { + if (!filesize($filePath)) { + unset($existingItemsByNames[$subDirItem]); + } + } + } + + $filesForSync = array(); + foreach ($filesByNamesFromFm as $fileName => $identity) { + if (!array_key_exists($fileName, $existingItemsByNames)) { + $filesForSync[] = $identity; + } + } + + $resultBody = array('success' => true, 'forward_code' => 200, 'files' => $filesForSync); +} catch (Exception $ex) { + $resultBody = array('success' => false, 'forward_code' => 500, 'message' => $ex->getMessage()); +} + +loadHeaders(); +setResponseCode(200); +echo json_encode($resultBody); diff --git a/public/vikon_core/update/update_module_version.php b/public/vikon_core/update/update_module_version.php new file mode 100644 index 0000000..d0c4dc6 --- /dev/null +++ b/public/vikon_core/update/update_module_version.php @@ -0,0 +1,80 @@ +curlHasError) { + sendErrorResponse(500, 'CURL ' . $res->curlErrorTxt); +} +if ($res->code !== 200) { + $err = 'Ошибка проверки подлинности токена. ' + . (!empty($res->responseBody->message) ? $res->responseBody->message : 'Неизвестная ошибка'); + sendErrorResponse($res->code, $err); +} + +try { + $tmpPath = Path::join(Path::getCoreRootPath(), 'tmp'); + if (!Filesystem::safeMkdir($tmpPath, 0755)) { + throw new RuntimeException('Не удалось создать директорию "' . $tmpPath . '" на вашем сервере'); + } + + $moduleVersionsPath = Path::join($tmpPath, 'versions'); + + if (!Filesystem::safeMkdir($moduleVersionsPath, 0755)) { + throw new RuntimeException('Не удалось создать директорию "' . $moduleVersionsPath . '" на вашем сервере'); + } + $moduleVersionFilePath = Path::join($moduleVersionsPath, $moduleId . '.json'); + + if (!Filesystem::remove($moduleVersionFilePath, false)) { + throw new RuntimeException('Не удалось удалить файл "' . $moduleVersionFilePath . '" на вашем сервере'); + } + + $json = json_encode(array('version' => $version)); + if (!Filesystem::safeMkfile($moduleVersionFilePath, 0755, $json)) { + throw new Exception('Не удалось записать служебную информацию в директорию: ' . $moduleVersionFilePath); + } +} catch (Exception $ex) { + sendErrorResponse(500, $ex->getMessage()); +} + +sendSuccessResponse(''); diff --git a/public/vikon_core/update/vsoko_feedback.php b/public/vikon_core/update/vsoko_feedback.php new file mode 100644 index 0000000..11a3e50 --- /dev/null +++ b/public/vikon_core/update/vsoko_feedback.php @@ -0,0 +1,77 @@ + $clientId, + 'client_secret' => $clientSecret, + 'grant_type' => 'client_credentials', + ), $headers + ); + + if ($data->code == 200) { + if (isset($data->responseBody)) { + $accessToken = $data->responseBody->access_token; + + try { + $data = remoteRequest($apiDomen . 'oauth-via-app/vsoko/feedbackSendMail?access_token=' + . $accessToken . + '&name=' . urlencode($name) . + '&email=' . urlencode($email) . + '&message=' . urlencode($message) + ); + + if ($data->code == 200) { + $res['success'] = true; + } else { + sendErrorResponse($data->code, $data->responseBody->message); + } + + } catch (Exception $e) { + $res['message'] = 'Ошибка. '.$e->getMessage(); + } + + } else { + $res['message'] = 'Ошибка ' . $data->responseBody->message; + } + } else { + $res['message'] = $data->responseBody->message; + } +} + +loadHeaders(); + +echo json_encode($res); diff --git a/public/vikon_core/update/zip_helper.php b/public/vikon_core/update/zip_helper.php new file mode 100755 index 0000000..cc1bf90 --- /dev/null +++ b/public/vikon_core/update/zip_helper.php @@ -0,0 +1,5451 @@ +zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; + + // ----- Return + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array(PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional', + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } elseif ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } // ----- Look if the $p_filelist is a string + elseif (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } else { + } + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes = array(PCLZIP_ATT_FILE_NAME => 'mandatory', + PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional', + PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional', + PCLZIP_ATT_FILE_MTIME => 'optional', + PCLZIP_ATT_FILE_CONTENT => 'optional', + PCLZIP_ATT_FILE_COMMENT => 'optional'); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array(PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional', + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } elseif ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } // ----- Look if the $p_filelist is a string + elseif (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '" . gettype($p_filelist) . "' for p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array(PCLZIP_ATT_FILE_NAME => 'mandatory', + PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional', + PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional', + PCLZIP_ATT_FILE_MTIME => 'optional', + PCLZIP_ATT_FILE_CONTENT => 'optional', + PCLZIP_ATT_FILE_COMMENT => 'optional',); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return (0); + } + + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) { + unset($p_list); + return (0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return (0); + } + + // ----- Set default values + $v_options = array(); + // $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array(PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional', + PCLZIP_OPT_STOP_ON_ERROR => 'optional', + PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional', + ) + ); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } elseif ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Trace + + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return (0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return (0); + } + + // ----- Set default values + $v_options = array(); + // $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array( + PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional', + PCLZIP_OPT_STOP_ON_ERROR => 'optional', + PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional', + ) + ); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false; + } else { + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } elseif ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Trace + + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array(PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array(PCLZIP_OPT_BY_INDEX => 'optional')); + if ($v_result != 1) { + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return (0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return (0); + } + + // ----- Set default values + $v_options = array(); + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array(PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + ) + ); + if ($v_result != 1) { + return 0; + } + } + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return (0); + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) + { + + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return (0); + } + + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; + + // ----- Look if file exists + if (@is_file($this->zipname)) { + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode'); + + // ----- Return + return 0; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privSwapBackMagicQuotes(); + return 0; + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_prop; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) { + + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } // ----- Look if the $p_archive is a string (so a filename) + elseif (is_string($p_archive)) { + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '" . $p_archive . "'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } + } // ----- Invalid variable + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return (0); + } + + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) { + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } // ----- Look if the $p_archive_to_add is a string (so a filename) + elseif (is_string($p_archive_to_add)) { + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); + } // ----- Invalid variable + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return (PclErrorCode()); + } else { + return ($this->error_code); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code = false) + { + $v_name = array( + PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', + PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', + PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION', + ); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return ($v_value . ' (' . $this->error_code . ')'); + } else { + return ($v_value); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full = false) + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return (PclErrorString()); + } else { + if ($p_full) { + return ($this->errorName(true) . " : " . $this->error_string); + } else { + return ($this->error_string . " [code " . $this->error_code . "]"); + } + } + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** + // ***** ***** + // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level = 0) + { + $v_result = true; + + // ----- Reset the file system cache + clearstatcache(); + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '" . $this->zipname . "'"); + return (false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '" . $this->zipname . "'"); + return (false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options = false) + { + $v_result = 1; + + // ----- Read the options + $i = 0; + while ($i < $p_size) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '" . $p_options_list[$i] . "' for this method"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i + 1], false); + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_THRESHOLD : + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i + 1]; + if ((!is_integer($v_value)) || ($v_value < 0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + return PclZip::errorCode(); + } + + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value * 1048576; + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_ON : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_TEMP_FILE_OFF : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i + 1]) + && ($p_options_list[$i + 1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i + 1], false); + $i++; + } else { + } + break; + + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i + 1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i + 1]; + } elseif (is_array($p_options_list[$i + 1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i + 1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + . PclZipUtilOptionText($p_options_list[$i]) + . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i + 1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + . PclZipUtilOptionText($p_options_list[$i]) + . "'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i + 1])) { + + // ----- Remove spaces + $p_options_list[$i + 1] = strtr($p_options_list[$i + 1], ' ', ''); + + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i + 1]); + } elseif (is_integer($p_options_list[$i + 1])) { + $v_work_list[0] = $p_options_list[$i + 1] . '-' . $p_options_list[$i + 1]; + } elseif (is_array($p_options_list[$i + 1])) { + $v_work_list = $p_options_list[$i + 1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag = false; + $v_sort_value = 0; + for ($j = 0; $j < sizeof($v_work_list); $j++) { + // ----- Explode the item + $v_item_list = explode("-", $v_work_list[$j]); + $v_size_item_list = sizeof($v_item_list); + + // ----- TBC : Here we might check that each item is a + // real integer ... + + // ----- Look for single value + if ($v_size_item_list == 1) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; + } elseif ($v_size_item_list == 2) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + } else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + + // ----- Look for list sort + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { + $v_sort_flag = true; + + // ----- TBC : An automatic sort should be writen ... + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; + } + + // ----- Sort the items + if ($v_sort_flag) { + // TBC : To Be Completed + } + + // ----- Next option + $i++; + break; + + // ----- Look for options that request no value + case PCLZIP_OPT_REMOVE_ALL_PATH : + case PCLZIP_OPT_EXTRACT_AS_STRING : + case PCLZIP_OPT_NO_COMPRESSION : + case PCLZIP_OPT_EXTRACT_IN_OUTPUT : + case PCLZIP_OPT_REPLACE_NEWER : + case PCLZIP_OPT_STOP_ON_ERROR : + $v_result_list[$p_options_list[$i]] = true; + break; + + // ----- Look for options that request an octal value + case PCLZIP_OPT_SET_CHMOD : + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1]; + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i + 1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_function_name = $p_options_list[$i + 1]; + + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '" . $v_function_name . "()' is not an existing function for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" + . $p_options_list[$i] . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Next options + $i++; + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key = reset($v_requested_options); $key = key($v_requested_options); $key = next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter " . PclZipUtilOptionText($key) . "(" . $key . ")"); + + // ----- Return + return PclZip::errorCode(); + } + } + } + } + + // ----- Look for default values + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOptionDefaultThreshold() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privOptionDefaultThreshold(&$p_options) + { + $v_result = 1; + + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + return $v_result; + } + + // ----- Get 'memory_limit' configuration value + $v_memory_limit = ini_get('memory_limit'); + $v_memory_limit = trim($v_memory_limit); + $last = strtolower(substr($v_memory_limit, -1)); + + if ($last == 'g') + //$v_memory_limit = $v_memory_limit*1024*1024*1024; + $v_memory_limit = $v_memory_limit * 1073741824; + if ($last == 'm') + //$v_memory_limit = $v_memory_limit*1024*1024; + $v_memory_limit = $v_memory_limit * 1048576; + if ($last == 'k') + $v_memory_limit = $v_memory_limit * 1024; + + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit * PCLZIP_TEMPORARY_FILE_RATIO); + + + // ----- Sanity check : No threshold if value lower than 1M + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options = false) + { + $v_result = 1; + + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '" . $v_key . "' for this file"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'"); + return PclZip::errorCode(); + } + + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '" . PclZipUtilOptionText($v_key) . "'"); + return PclZip::errorCode(); + } + + break; + + case PCLZIP_ATT_FILE_NEW_SHORT_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '" . PclZipUtilOptionText($v_key) . "'"); + return PclZip::errorCode(); + } + break; + + case PCLZIP_ATT_FILE_NEW_FULL_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '" . PclZipUtilOptionText($v_key) . "'"); + return PclZip::errorCode(); + } + break; + + // ----- Look for options that takes a string + case PCLZIP_ATT_FILE_COMMENT : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'"); + return PclZip::errorCode(); + } + + $p_filedescr['comment'] = $v_value; + break; + + case PCLZIP_ATT_FILE_MTIME : + if (!is_integer($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". Integer expected for attribute '" . PclZipUtilOptionText($v_key) . "'"); + return PclZip::errorCode(); + } + + $p_filedescr['mtime'] = $v_value; + break; + + case PCLZIP_ATT_FILE_CONTENT : + $p_filedescr['content'] = $v_value; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" . $v_key . "'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key = reset($v_requested_options); $key = key($v_requested_options); $key = next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter " . PclZipUtilOptionText($key) . "(" . $key . ")"); + return PclZip::errorCode(); + } + } + } + } + + // end foreach + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrExpand() + // Description : + // This method look for each item of the list to see if its a file, a folder + // or a string to be added as file. For any other type of files (link, other) + // just ignore the item. + // Then prepare the information that will be stored for that file. + // When its a folder, expand the folder with all the files that are in that + // folder (recursively). + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrExpand(&$p_filedescr_list, &$p_options) + { + $v_result = 1; + + // ----- Create a result list + $v_result_list = array(); + + // ----- Look each entry + for ($i = 0; $i < sizeof($p_filedescr_list); $i++) { + + // ----- Get filedescr + $v_descr = $p_filedescr_list[$i]; + + // ----- Reduce the filename + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); + + // ----- Look for real file or folder + if (file_exists($v_descr['filename'])) { + if (@is_file($v_descr['filename'])) { + $v_descr['type'] = 'file'; + } elseif (@is_dir($v_descr['filename'])) { + $v_descr['type'] = 'folder'; + } elseif (@is_link($v_descr['filename'])) { + // skip + continue; + } else { + // skip + continue; + } + } // ----- Look for string added as file + elseif (isset($v_descr['content'])) { + $v_descr['type'] = 'virtual_file'; + } // ----- Missing file + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $v_descr['filename'] . "' does not exist"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Calculate the stored filename + $this->privCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; + } + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'] . '/' . $v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if (($v_descr['stored_filename'] != $v_descr['filename']) + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + if ($v_descr['stored_filename'] != '') { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'] . '/' . $v_item_handler; + } else { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + } + } + + $v_dirlist_nb++; + } + + @closedir($v_folder_handler); + } else { + // TBC : unable to open folder in read mode + } + + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + return $v_result; + } + + // ----- Concat the resulting list + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + } else { + } + + // ----- Free local array + unset($v_dirlist_descr); + } + } + + // ----- Get the result list + $p_filedescr_list = $v_result_list; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result = 1; + $v_list_detail = array(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) { + // ----- Return + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); + + // ----- Close + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result = 1; + $v_list_detail = array(); + + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) { + + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); + + // ----- Return + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i = 0, $v_count = 0; $i < sizeof($v_header_list); $i++) { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment . $p_options[PCLZIP_OPT_ADD_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT] . $v_comment; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd) - $v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count + $v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) + { + $v_result = 1; + + // ----- Look if already open + if ($this->zip_fd != 0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \'' . $this->zipname . '\' already open'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in ' . $p_mode . ' mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() + { + $v_result = 1; + + if ($this->zip_fd != 0) + @fclose($this->zip_fd); + $this->zip_fd = 0; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- + // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result = 1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) { + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Create the Central Dir files header + for ($i = 0, $v_count = 0; $i < sizeof($v_header_list); $i++) { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd) - $v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result = 1; + $v_header = array(); + + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); + + // ----- Loop on the files + for ($j = 0; ($j < sizeof($p_filedescr_list)) && ($v_result == 1); $j++) { + // ----- Format the filename + $p_filedescr_list[$j]['filename'] + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); + + + // ----- Skip empty file names + // TBC : Can this be possible ? not checked in DescrParseAtt ? + if ($p_filedescr_list[$j]['filename'] == "") { + continue; + } + + // ----- Check the filename + if (($p_filedescr_list[$j]['type'] != 'virtual_file') + && (!file_exists($p_filedescr_list[$j]['filename']))) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $p_filedescr_list[$j]['filename'] . "' does not exist"); + return PclZip::errorCode(); + } + + // ----- Look if it is a file or a dir with no all path remove option + // or a dir with all its path removed + // if ( (is_file($p_filedescr_list[$j]['filename'])) + // || ( is_dir($p_filedescr_list[$j]['filename']) + if (($p_filedescr_list[$j]['type'] == 'file') + || ($p_filedescr_list[$j]['type'] == 'virtual_file') + || (($p_filedescr_list[$j]['type'] == 'folder') + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) + ) { + + // ----- Add the file + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, + $p_options); + if ($v_result != 1) { + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) + { + $v_result = 1; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for a stored different filename + /* TBC : Removed + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; + } + */ + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; + // TBC : Removed $p_header['stored_filename'] = $v_stored_filename; + $p_header['stored_filename'] = $p_filedescr['stored_filename']; + $p_header['extra'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for regular file + if ($p_filedescr['type'] == 'file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = filesize($p_filename); + } // ----- Look for regular folder + elseif ($p_filedescr['type'] == 'folder') { + $p_header['external'] = 0x00000010; + $p_header['mtime'] = filemtime($p_filename); + $p_header['size'] = filesize($p_filename); + } // ----- Look for virtual file + elseif ($p_filedescr['type'] == 'virtual_file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = strlen($p_filedescr['content']); + } + + + // ----- Look for filetime + if (isset($p_filedescr['mtime'])) { + $p_header['mtime'] = $p_filedescr['mtime']; + } elseif ($p_filedescr['type'] == 'virtual_file') { + $p_header['mtime'] = time(); + } else { + $p_header['mtime'] = filemtime($p_filename); + } + + // ------ Look for file comment + if (isset($p_filedescr['comment'])) { + $p_header['comment_len'] = strlen($p_filedescr['comment']); + $p_header['comment'] = $p_filedescr['comment']; + } else { + $p_header['comment_len'] = 0; + $p_header['comment'] = ''; + } + + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + } + } + + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } + + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if ($p_filedescr['type'] == 'file') { + // ----- Look for using temporary file to zip + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])))) { + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } // ----- Use "in memory" zip algo + else { + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Close the file + @fclose($v_file); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + + } + + } // ----- Look for a virtual file (a file from string) + elseif ($p_filedescr['type'] == 'virtual_file') { + + $v_content = $p_filedescr['content']; + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + } // ----- Look for a directory + elseif ($p_filedescr['type'] == 'folder') { + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } + + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + } + } + + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + { + $v_result = PCLZIP_ERR_NO_ERROR; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Creates a compressed temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.gz'; + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = filesize($p_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @gzputs($v_file_compressed, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file); + @gzclose($v_file_compressed); + + // ----- Check the minimum file size + if (filesize($v_gzip_temp_name) < 18) { + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \'' . $v_gzip_temp_name . '\' has invalid filesize - should be minimum 18 bytes'); + return PclZip::errorCode(); + } + + // ----- Extract the compressed attributes + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the gzip file header + $v_binary_data = @fread($v_file_compressed, 10); + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); + + // ----- Check some parameters + $v_data_header['os'] = bin2hex($v_data_header['os']); + + // ----- Read the gzip file footer + @fseek($v_file_compressed, filesize($v_gzip_temp_name) - 8); + $v_binary_data = @fread($v_file_compressed, 8); + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); + + // ----- Set the attributes + $p_header['compression'] = ord($v_data_header['cm']); + //$p_header['mtime'] = $v_data_header['mtime']; + $p_header['crc'] = $v_data_footer['crc']; + $p_header['compressed_size'] = filesize($v_gzip_temp_name) - 18; + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + + // ----- Add the compressed data + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + fseek($v_file_compressed, 10); + $v_size = $p_header['compressed_size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Unlink the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) + { + $v_result = 1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } else { + $p_remove_all_dir = 0; + } + + + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); + } // ----- Look for path and/or short name change + else { + + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'] . '/'; + } + $v_stored_filename = $v_dir . $p_filedescr['new_short_name']; + } else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } // ----- Look for partial path remove + elseif ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ((substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ((substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./" . $p_remove_dir; + } + if ((substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } + + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; + } else { + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + } + } + } + + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); + + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir . $v_stored_filename; + else + $v_stored_filename = $p_add_dir . "/" . $v_stored_filename; + } + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) + { + $v_result = 1; + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours'] << 11) + ($v_date['minutes'] << 5) + $v_date['seconds'] / 2; + $v_mdate = (($v_date['year'] - 1980) << 9) + ($v_date['mon'] << 5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) + { + $v_result = 1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours'] << 11) + ($v_date['minutes'] << 5) + $v_date['seconds'] / 2; + $v_mdate = (($v_date['year'] - 1980) << 9) + ($v_date['mon'] << 5) + $v_date['mday']; + + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + $v_result = 1; + + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); + + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); + + // ----- Write the variable fields + if (strlen($p_comment) != 0) { + fputs($this->zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) + { + $v_result = 1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of Central Dir + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + for ($i = 0; $i < $v_central_dir['entries']; $i++) { + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // $p_info['crc'] = CRC of the file content. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) + { + $v_result = 1; + + // ----- Get the interesting attributes + $v_temp_path = PclZipUtilPathReduction($p_header['filename']); + $p_info['filename'] = $v_temp_path; + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); + $p_info['stored_filename'] = $v_temp_path; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external'] & 0x00000010) == 0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + $p_info['crc'] = $p_header['crc']; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result = 1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check the path + if (($p_path == "") + || ((substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path, 1, 2) != ":/"))) + $p_path = "./" . $p_path; + + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") { + $p_path = substr($p_path, 0, strlen($p_path) - 1); + } + } + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + + // ----- Read each entry + $j_start = 0; + for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) { + + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ((isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j = 0; ($j < sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ((strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_extract = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + */ + + // ----- Look for extract by preg rule + elseif ((isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } // ----- Look for extract by index rule + elseif ((isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j = $j_start; ($j < sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + + if (($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j + 1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) { + break; + } + } + } // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } + + // ----- Check compression method + if (($v_extract) + && (($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '" . $v_header['stored_filename'] . "' is " + . "compressed by an unsupported compression " + . "method (" . $v_header['compression'] . ") "); + + return PclZip::errorCode(); + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + . " filename '" . $v_header['stored_filename'] + . "'"); + + return PclZip::errorCode(); + } + } + + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + $v_extract = false; + } + + // ----- Look for real extraction + if ($v_extract) { + + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + + $v_string = ''; + + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } // ----- Look for extraction in standard output + elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + } + } + + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result = 1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external'] & 0x00000010) == 0x00000010) { + + $p_entry['status'] = "filtered"; + + return $v_result; + } + + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } // ----- Look for path to remove + elseif ($p_remove_path != "") { + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) { + + // ----- Change the file status + $p_entry['status'] = "filtered"; + + // ----- Return + return $v_result; + } + + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) { + + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + + } + } + + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path . "/" . $p_entry['filename']; + } + + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { + + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '" . $p_entry['filename'] . "' is " + . "outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + + return PclZip::errorCode(); + } + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) { + + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { + + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '" . $p_entry['filename'] . "' is " + . "already used by an existing directory"); + + return PclZip::errorCode(); + } + } // ----- Look if file is write protected + elseif (!is_writeable($p_entry['filename'])) { + + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '" . $p_entry['filename'] . "' exists " + . "and is write protected"); + + return PclZip::errorCode(); + } + } // ----- Look if the extracted file is older + elseif (filemtime($p_entry['filename']) > $p_entry['mtime']) { + // ----- Change the file status + if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER] === true)) { + } else { + $p_entry['status'] = "newer_exist"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '" . $p_entry['filename'] . "' exists " + . "and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + + return PclZip::errorCode(); + } + } + } else { + } + } // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external'] & 0x00000010) == 0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + elseif (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external'] & 0x00000010) == 0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } + } + } + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + + + } else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \'' . $p_entry['filename'] . '\' is encrypted. Encrypted files are not supported.'); + return PclZip::errorCode(); + } + + + // ----- Look for using temporary file to unzip + if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])))) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } // ----- Look for extract in memory + else { + + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === false) { + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + } + + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } + + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileUsingTempFile(&$p_entry, &$p_options) + { + $v_result = 1; + + // ----- Creates a temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.gz'; + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode'); + return PclZip::errorCode(); + } + + + // ----- Write gz file format header + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); + @fwrite($v_dest_file, $v_binary_data, 10); + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Write gz file format footer + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); + @fwrite($v_dest_file, $v_binary_data, 8); + + // ----- Close the temporary file + @fclose($v_dest_file); + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; + } + + // ----- Open the temporary gz file + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode'); + return PclZip::errorCode(); + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + @fclose($v_dest_file); + @gzclose($v_src_file); + + // ----- Delete the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + $v_result = 1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + // ----- Trace + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { + + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } else { + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + { + $v_result = 1; + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) { + // ----- Look for not compressed file + // if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { + + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === false) { + // TBC + } + } + + // ----- Trace + } else { + // TBC : error : can not extract a folder in a string + } + + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) + { + $v_result = 1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x04034b50) { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + + // ----- Get filename + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } else { + $p_header['extra'] = ''; + } + + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + $p_header['filename_len'] = $v_data['filename_len']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F) * 2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } else { + $p_header['mtime'] = time(); + } + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) + { + $v_result = 1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x02014b50) { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; + + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; + + // ----- Extract properties + + // ----- Recuperate date in UNIX format + //if ($p_header['mdate'] && $p_header['mtime']) + // TBC : bug : this was ignoring time with 0/0/0 + if (1) { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F) * 2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } else { + $p_header['mtime'] = time(); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; + } + + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) + { + $v_result = 1; + + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } + + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) + { + $v_result = 1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + @fseek($this->zip_fd, $v_size); + if (@ftell($this->zip_fd) != $v_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \'' . $this->zipname . '\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->zip_fd, $v_size - 22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size - 22)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } + + $v_pos = ftell($this->zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size - $v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size - $v_maximum_size)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); + + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) { + $v_pos++; + break; + } + + $v_pos++; + } + + // ----- Look if not found end of central dir + if ($v_pos == $v_size) { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : " . strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + . ' Some trailing bytes exists after the archive.'); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Get comment + if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); + } else + $p_central_dir['comment'] = ''; + + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; + + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + //} + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) + { + $v_result = 1; + $v_list_detail = array(); + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) { + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) { + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + + return $v_result; + } + + + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ((isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j = 0; ($j < sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ((strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } elseif ((($v_header_list[$v_nb_extracted]['external'] & 0x00000010) == 0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'] . '/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + */ + + // ----- Look for extract by preg rule + elseif ((isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } // ----- Look for extract by index rule + elseif ((isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j = $j_start; ($j < sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { + + if (($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j + 1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) { + break; + } + } + } else { + $v_found = true; + } + + // ----- Look for deletion + if ($v_found) { + unset($v_header_list[$v_nb_extracted]); + } else { + $v_nb_extracted++; + } + } + + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp'; + + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); + + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Look which file need to be kept + for ($i = 0; $i < sizeof($v_header_list); $i++) { + + // ----- Calculate the position of the header + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); + + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); + + // ----- Re-Create the Central Dir files header + for ($i = 0; $i < sizeof($v_header_list); $i++) { + // ----- Create the file header + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd) - $v_offset; + + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } // ----- Remove every files : reset the file + elseif ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); + + if (($v_result = $this->privOpenFd('wb')) != 1) { + return $v_result; + } + + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + return $v_result; + } + + $this->privCloseFd(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir = false) + { + $v_result = 1; + + + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1) == '/')) { + $p_dir = substr($p_dir, 0, strlen($p_dir) - 1); + } + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) { + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + + // ----- Just a check + if ($p_parent_dir != $p_dir) { + // ----- Look for parent directory + if ($p_parent_dir != "") { + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) { + return $v_result; + } + } + } + + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) + { + $v_result = 1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) { + + // ----- Nothing to merge, so merge is a success + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Look if the archive exists + if (!is_file($this->zipname)) { + + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Open the archive_to_add file + if (($v_result = $p_archive_to_add->privOpenFd('rb')) != 1) { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + return $v_result; + } + + // ----- Go to beginning of File + @rewind($p_archive_to_add->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'] . ' ' . $v_central_dir_to_add['comment']; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd) - $v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries'] + $v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) + { + $v_result = 1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) { + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('wb')) != 1) { + // ----- Return + return $v_result; + } + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) { + $this->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \'' . $p_archive_filename . '\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code = 0, $p_error_string = '') + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } else { + $this->error_code = 0; + $this->error_string = ''; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() + { + $v_result = 1; + + // ----- Look if function exists + if ((!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); + + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + $v_result = 1; + + // ----- Look if function exists + if ((!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + +} + +// End of class +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilPathReduction() +// Description : +// Parameters : +// Return Values : +// -------------------------------------------------------------------------------- +function PclZipUtilPathReduction($p_dir) +{ + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i = sizeof($v_list) - 1; $i >= 0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } elseif ($v_list[$i] == "..") { + $v_skip++; + } elseif ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/" . $v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; + } + } // ----- Last '/' i.e. indicates a directory + elseif ($i == (sizeof($v_list) - 1)) { + $v_result = $v_list[$i]; + } // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } else { + $v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? "/" . $v_result : ""); + } + } + } + + // ----- Look for skip + if ($v_skip > 0) { + while ($v_skip > 0) { + $v_result = '../' . $v_result; + $v_skip--; + } + } + } + + // ----- Return + return $v_result; +} + +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilPathInclusion() +// Description : +// This function indicates if the path $p_path is under the $p_dir tree. Or, +// said in an other way, if the file or sub-dir $p_path is inside the dir +// $p_dir. +// The function indicates also if the path is exactly the same as the dir. +// This function supports path with duplicated '/' like '//', but does not +// support '.' or '..' statements. +// Parameters : +// Return Values : +// 0 if $p_path is not inside directory $p_dir +// 1 if $p_path is inside directory $p_dir +// 2 if $p_path is exactly the same as $p_dir +// -------------------------------------------------------------------------------- +function PclZipUtilPathInclusion($p_dir, $p_path) +{ + $v_result = 1; + + // ----- Look for path beginning by ./ + if (($p_dir == '.') + || ((strlen($p_dir) >= 2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), false) . '/' . substr($p_dir, 1); + } + if (($p_path == '.') + || ((strlen($p_path) >= 2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), false) . '/' . substr($p_path, 1); + } + + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); + + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) { + $v_result = 0; + } + + // ----- Next items + $i++; + $j++; + } + + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } elseif ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } + + // ----- Return + return $v_result; +} + +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilCopyBlock() +// Description : +// Parameters : +// $p_mode : read/write compression mode +// 0 : src & dest normal +// 1 : src gzip, dest normal +// 2 : src normal, dest gzip +// 3 : src & dest gzip +// Return Values : +// -------------------------------------------------------------------------------- +function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode = 0) +{ + $v_result = 1; + + if ($p_mode == 0) { + while ($p_size != 0) { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } elseif ($p_mode == 1) { + while ($p_size != 0) { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } elseif ($p_mode == 2) { + while ($p_size != 0) { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } elseif ($p_mode == 3) { + while ($p_size != 0) { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + + // ----- Return + return $v_result; +} + +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilRename() +// Description : +// This function tries to do a simple rename() function. If it fails, it +// tries to copy the $p_src file in a new $p_dest file and then unlink the +// first one. +// Parameters : +// $p_src : Old filename +// $p_dest : New filename +// Return Values : +// 1 on success, 0 on failure. +// -------------------------------------------------------------------------------- +function PclZipUtilRename($p_src, $p_dest) +{ + $v_result = 1; + + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { + + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } elseif (!@unlink($p_src)) { + $v_result = 0; + } + } + + // ----- Return + return $v_result; +} + +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilOptionText() +// Description : +// Translate option value in text. Mainly for debug purpose. +// Parameters : +// $p_option : the option value. +// Return Values : +// The option text value. +// -------------------------------------------------------------------------------- +function PclZipUtilOptionText($p_option) +{ + + $v_list = get_defined_constants(); + for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if ((($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + return $v_key; + } + } + + $v_result = 'Unknown'; + + return $v_result; +} + +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Function : PclZipUtilTranslateWinPath() +// Description : +// Translate windows path by replacing '\' by '/' and optionally removing +// drive letter. +// Parameters : +// $p_path : path to translate. +// $p_remove_disk_letter : true | false +// Return Values : +// The path translated. +// -------------------------------------------------------------------------------- +function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter = true) +{ + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position + 1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; +} +// -------------------------------------------------------------------------------- \ No newline at end of file