From 7e4e374f621d9d1c37f37ff6555e013cdb3b03a0 Mon Sep 17 00:00:00 2001 From: abc <98614666+xtekky@users.noreply.github.com> Date: Fri, 6 Oct 2023 19:52:17 +0100 Subject: [PATCH] ~ | new g4f GUI --- g4f/gui/__init__.py | 30 + g4f/gui/client/css/style.css | 861 ++++++++++++++++++ g4f/gui/client/html/index.html | 161 ++++ g4f/gui/client/img/android-chrome-192x192.png | Bin 0 -> 8908 bytes g4f/gui/client/img/android-chrome-512x512.png | Bin 0 -> 17626 bytes g4f/gui/client/img/apple-touch-icon.png | Bin 0 -> 7984 bytes g4f/gui/client/img/favicon-16x16.png | Bin 0 -> 499 bytes g4f/gui/client/img/favicon-32x32.png | Bin 0 -> 1041 bytes g4f/gui/client/img/gpt.png | Bin 0 -> 2885 bytes g4f/gui/client/img/site.webmanifest | 19 + g4f/gui/client/img/user.png | Bin 0 -> 17004 bytes g4f/gui/client/js/chat.v2.js | 620 +++++++++++++ g4f/gui/client/js/highlight.min.js | 1 + g4f/gui/client/js/highlightjs-copy.min.js | 1 + g4f/gui/client/js/icons.js | 1 + g4f/gui/server/app.py | 3 + g4f/gui/server/backend.py | 52 ++ g4f/gui/server/config.py | 63 ++ g4f/gui/server/internet.py | 28 + g4f/gui/server/website.py | 40 + 20 files changed, 1880 insertions(+) create mode 100644 g4f/gui/__init__.py create mode 100644 g4f/gui/client/css/style.css create mode 100644 g4f/gui/client/html/index.html create mode 100644 g4f/gui/client/img/android-chrome-192x192.png create mode 100644 g4f/gui/client/img/android-chrome-512x512.png create mode 100644 g4f/gui/client/img/apple-touch-icon.png create mode 100644 g4f/gui/client/img/favicon-16x16.png create mode 100644 g4f/gui/client/img/favicon-32x32.png create mode 100644 g4f/gui/client/img/gpt.png create mode 100644 g4f/gui/client/img/site.webmanifest create mode 100644 g4f/gui/client/img/user.png create mode 100644 g4f/gui/client/js/chat.v2.js create mode 100644 g4f/gui/client/js/highlight.min.js create mode 100644 g4f/gui/client/js/highlightjs-copy.min.js create mode 100644 g4f/gui/client/js/icons.js create mode 100644 g4f/gui/server/app.py create mode 100644 g4f/gui/server/backend.py create mode 100644 g4f/gui/server/config.py create mode 100644 g4f/gui/server/internet.py create mode 100644 g4f/gui/server/website.py diff --git a/g4f/gui/__init__.py b/g4f/gui/__init__.py new file mode 100644 index 00000000..90a6c7a6 --- /dev/null +++ b/g4f/gui/__init__.py @@ -0,0 +1,30 @@ +from .server.app import app +from .server.website import Website +from .server.backend import Backend_Api + +def run_gui(host: str = '0.0.0.0', port: int = 80, debug: bool = False) -> None: + config = { + 'host' : host, + 'port' : port, + 'debug': debug + } + + site = Website(app) + for route in site.routes: + app.add_url_rule( + route, + view_func = site.routes[route]['function'], + methods = site.routes[route]['methods'], + ) + + backend_api = Backend_Api(app) + for route in backend_api.routes: + app.add_url_rule( + route, + view_func = backend_api.routes[route]['function'], + methods = backend_api.routes[route]['methods'], + ) + + print(f"Running on port {config['port']}") + app.run(**config) + print(f"Closing port {config['port']}") \ No newline at end of file diff --git a/g4f/gui/client/css/style.css b/g4f/gui/client/css/style.css new file mode 100644 index 00000000..e68b9094 --- /dev/null +++ b/g4f/gui/client/css/style.css @@ -0,0 +1,861 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap"); + +.adsbox { + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + height: 100%; + width: 100%; + border-radius: var(--border-radius-1); + border: 1px solid var(--blur-border); +} + +.ads { + align-items: center; + margin: auto; + display: flex; + flex-direction: column; + gap: 16px; + max-width: 200px; + padding: var(--section-gap); + overflow: none; + flex-shrink: 0; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +@media screen and (max-width: 728px) { + .ads { + display: none; + } +} + +/* :root { + --colour-1: #ffffff; + --colour-2: #000000; + --colour-3: #000000; + --colour-4: #000000; + --colour-5: #000000; + --colour-6: #000000; + + --accent: #ffffff; + --blur-bg: #98989866; + --blur-border: #00000040; + --user-input: #000000; + --conversations: #000000; +} */ + +:root { + --colour-1: #000000; + --colour-2: #ccc; + --colour-3: #e4d4ff; + --colour-4: #f0f0f0; + --colour-5: #181818; + --colour-6: #242424; + + --accent: #8b3dff; + --blur-bg: #16101b66; + --blur-border: #84719040; + --user-input: #ac87bb; + --conversations: #c7a2ff; + --conversations-hover: #c7a2ff4d; +} + +:root { + --font-1: "Inter", sans-serif; + --section-gap: 25px; + --border-radius-1: 8px; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + position: relative; + font-family: var(--font-1); +} + +html, +body { + scroll-behavior: smooth; + overflow: hidden; +} + +body { + padding: var(--section-gap); + background: var(--colour-1); + color: var(--colour-3); + height: 100vh; +} + +.row { + display: flex; + gap: var(--section-gap); + height: 100%; +} + +.box { + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + height: 100%; + width: 100%; + border-radius: var(--border-radius-1); + border: 1px solid var(--blur-border); +} + +.conversations { + max-width: 260px; + padding: var(--section-gap); + overflow: auto; + flex-shrink: 0; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.conversation { + width: 100%; + display: flex; + flex-direction: column; + gap: 15px; +} + +.conversation #messages { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + overflow: auto; + overflow-wrap: break-word; + padding-bottom: 50px; +} + +.conversation .user-input { + max-height: 200px; +} + +.conversation .user-input input { + font-size: 15px; + width: 100%; + height: 100%; + padding: 12px 15px; + background: none; + border: none; + outline: none; + color: var(--colour-3); +} + +.conversation .user-input input::placeholder { + color: var(--user-input) +} + +.gradient:nth-child(1) { + --top: 0; + --right: 0; + --size: 70vw; + --blur: calc(0.5 * var(--size)); + --opacity: 0.3; + animation: zoom_gradient 6s infinite; +} + +.gradient { + position: absolute; + z-index: -1; + border-radius: calc(0.5 * var(--size)); + background-color: var(--accent); + background: radial-gradient(circle at center, var(--accent), var(--accent)); + width: 70vw; + height: 70vw; + top: 50%; + right: 0; + transform: translateY(-50%); + filter: blur(calc(0.5 * 70vw)) opacity(var(--opacity)); +} + +.conversations { + display: flex; + flex-direction: column; + gap: 16px; +} + +.conversations .title { + font-size: 14px; + font-weight: 500; +} + +.conversations .convo { + padding: 8px 12px; + display: flex; + gap: 10px; + align-items: center; + user-select: none; + justify-content: space-between; + border: 1px dashed var(--conversations); + border-radius: var(--border-radius-1); +} + +.conversations .convo .left { + cursor: pointer; + display: flex; + align-items: center; + gap: 10px; +} + +.conversations i { + color: var(--conversations); + cursor: pointer; +} + +.convo-title { + color: var(--colour-3); + font-size: 14px; +} + +.message { + + width: 100%; + overflow-wrap: break-word; + display: flex; + gap: var(--section-gap); + padding: var(--section-gap); + padding-bottom: 0; +} + +.message:last-child { + animation: 0.6s show_message; +} + +@keyframes show_message { + from { + transform: translateY(10px); + opacity: 0; + } +} + +.message .user { + max-width: 48px; + max-height: 48px; + flex-shrink: 0; +} + +.message .user img { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 8px; + outline: 1px solid var(--blur-border); +} + +.message .user:after { + content: "63"; + position: absolute; + bottom: 0; + right: 0; + height: 60%; + width: 60%; + background: var(--colour-3); + filter: blur(10px) opacity(0.5); + z-index: 10000; +} + +.message .content { + display: flex; + flex-direction: column; + gap: 18px; +} + +.message .content p, +.message .content li, +.message .content code { + font-size: 15px; + line-height: 1.3; +} + +.message .user i { + position: absolute; + bottom: -6px; + right: -6px; + z-index: 1000; +} + +.new_convo { + padding: 8px 12px; + display: flex; + gap: 18px; + align-items: center; + cursor: pointer; + user-select: none; + background: transparent; + border: 1px solid var(--conversations); + border-radius: var(--border-radius-1); + transition: all 0.2s ease; +} + +.new_convo:hover { + box-shadow: inset 0px 0px 20px var(--conversations-hover); +} + +.new_convo span { + color: var(--colour-3); + font-size: 14px; +} + + +.stop_generating { + position: absolute; + bottom: 118px; + /* left: 10px; + bottom: 125px; + right: 8px; */ + left: 50%; + transform: translateX(-50%); + z-index: 1000000; +} + +.stop_generating button { + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + border-radius: var(--border-radius-1); + border: 1px solid var(--blur-border); + padding: 10px 15px; + color: var(--colour-3); + display: flex; + justify-content: center; + align-items: center; + gap: 12px; + cursor: pointer; + animation: show_popup 0.4s; +} + +@keyframes show_popup { + from { + opacity: 0; + transform: translateY(10px); + } +} + +@keyframes hide_popup { + to { + opacity: 0; + transform: translateY(10px); + } +} + +.stop_generating-hiding button { + animation: hide_popup 0.4s; +} + +.stop_generating-hidden button { + display: none; +} + +.typing { + position: absolute; + top: -25px; + left: 0; + font-size: 14px; + animation: show_popup 0.4s; +} + +.typing-hiding { + animation: hide_popup 0.4s; +} + +.typing-hidden { + display: none; +} + +input[type="checkbox"] { + height: 0; + width: 0; + display: none; +} + +label { + cursor: pointer; + text-indent: -9999px; + width: 50px; + height: 30px; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + border-radius: var(--border-radius-1); + border: 1px solid var(--blur-border); + display: block; + border-radius: 100px; + position: relative; + overflow: hidden; + transition: 0.33s; +} + +label:after { + content: ""; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 5px; + width: 20px; + height: 20px; + background: var(--colour-3); + border-radius: 90px; + transition: 0.33s; +} + +input:checked+label { + background: var(--blur-border); +} + +input:checked+label:after { + left: calc(100% - 5px - 20px); +} + +.buttons { + display: flex; + align-items: center; + justify-content: left; + width: 100%; +} + +.field { + height: fit-content; + display: flex; + align-items: center; + gap: 16px; + padding-right: 15px +} + +.field .about { + font-size: 14px; + color: var(--colour-3); +} + + +select { + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + border-radius: 8px; + + -webkit-backdrop-filter: blur(20px); + backdrop-filter: blur(20px); + + cursor: pointer; + background-color: var(--blur-bg); + border: 1px solid var(--blur-border); + color: var(--colour-3); + display: block; + position: relative; + overflow: hidden; + outline: none; + padding: 8px 16px; + + appearance: none; +} + +.input-box { + display: flex; + align-items: center; + padding-right: 15px; + cursor: pointer; +} + +.info { + padding: 8px 12px; + display: flex; + gap: 18px; + align-items: center; + user-select: none; + background: transparent; + border-radius: var(--border-radius-1); + width: 100%; + cursor: default; + border: 1px dashed var(--conversations) +} + +.bottom_buttons { + width: 100%; + display: flex; + flex-direction: column; + gap: 10px; +} + +.bottom_buttons button { + padding: 8px 12px; + display: flex; + gap: 18px; + align-items: center; + cursor: pointer; + user-select: none; + background: transparent; + border: 1px solid var(--conversations); + border-radius: var(--border-radius-1); + width: 100%; +} + +.bottom_buttons button span { + color: var(--colour-3); + font-size: 14px; +} + +.conversations .top { + display: flex; + flex-direction: column; + gap: 16px; + overflow: auto; +} + + +#cursor { + line-height: 17px; + margin-left: 3px; + -webkit-animation: blink 0.8s infinite; + animation: blink 0.8s infinite; + width: 7px; + height: 15px; +} + +@keyframes blink { + 0% { + background: #ffffff00; + } + + 50% { + background: white; + } + + 100% { + background: #ffffff00; + } +} + +@-webkit-keyframes blink { + 0% { + background: #ffffff00; + } + + 50% { + background: white; + } + + 100% { + background: #ffffff00; + } +} + + +ol, +ul { + padding-left: 20px; +} + + +@keyframes spinner { + to { + transform: rotate(360deg); + } +} + +.spinner:before { + content: ''; + box-sizing: border-box; + position: absolute; + top: 50%; + left: 45%; + width: 20px; + height: 20px; + + border-radius: 50%; + border: 1px solid var(--conversations); + border-top-color: white; + animation: spinner .6s linear infinite; +} + +.grecaptcha-badge { + visibility: hidden; +} + +.mobile-sidebar { + display: none !important; + position: absolute; + z-index: 100000; + top: 0; + left: 0; + margin: 10px; + font-size: 20px; + cursor: pointer; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + background-color: var(--blur-bg); + border-radius: 10px; + border: 1px solid var(--blur-border); + width: 40px; + height: 40px; + justify-content: center; + align-items: center; + transition: 0.33s; +} + +.mobile-sidebar i { + transition: 0.33s; +} + +.rotated { + transform: rotate(360deg); +} + +@media screen and (max-width: 990px) { + .conversations { + display: none; + width: 100%; + max-width: none; + } + + .buttons { + align-items: flex-start; + flex-wrap: wrap; + gap: 15px; + } + + .field { + width: fit-content; + } + + .mobile-sidebar { + display: flex !important; + } +} + +@media screen and (max-height: 640px) { + body { + height: 87vh + } +} + + +.shown { + display: flex; +} + + +a:-webkit-any-link { + color: var(--accent); +} + +.conversation .user-input textarea { + font-size: 15px; + width: 100%; + height: 100%; + padding: 12px 15px; + background: none; + border: none; + outline: none; + color: var(--colour-3); + + resize: vertical; + max-height: 150px; + min-height: 80px; +} + +/* style for hljs copy */ +.hljs-copy-wrapper { + position: relative; + overflow: hidden +} + +.hljs-copy-wrapper:hover .hljs-copy-button, +.hljs-copy-button:focus { + transform: translateX(0) +} + +.hljs-copy-button { + position: absolute; + transform: translateX(calc(100% + 1.125em)); + top: 1em; + right: 1em; + width: 2rem; + height: 2rem; + text-indent: -9999px; + color: #fff; + border-radius: .25rem; + border: 1px solid #ffffff22; + background-color: #2d2b57; + background-image: url('data:image/svg+xml;utf-8,'); + background-repeat: no-repeat; + background-position: center; + transition: background-color 200ms ease, transform 200ms ease-out +} + +.hljs-copy-button:hover { + border-color: #ffffff44 +} + +.hljs-copy-button:active { + border-color: #ffffff66 +} + +.hljs-copy-button[data-copied="true"] { + text-indent: 0; + width: auto; + background-image: none +} + +@media(prefers-reduced-motion) { + .hljs-copy-button { + transition: none + } +} + +.hljs-copy-alert { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px +} + +.visually-hidden { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; +} + + +.color-picker>fieldset { + border: 0; + display: flex; + width: fit-content; + background: var(--colour-1); + margin-inline: auto; + border-radius: 8px; + -webkit-backdrop-filter: blur(20px); + backdrop-filter: blur(20px); + cursor: pointer; + background-color: var(--blur-bg); + border: 1px solid var(--blur-border); + color: var(--colour-3); + display: block; + position: relative; + overflow: hidden; + outline: none; + padding: 6px 16px; +} + +.color-picker input[type="radio"]:checked { + background-color: var(--radio-color); +} + +.color-picker input[type="radio"]#light { + --radio-color: gray; +} + +.color-picker input[type="radio"]#pink { + --radio-color: white; +} + +.color-picker input[type="radio"]#blue { + --radio-color: blue; +} + +.color-picker input[type="radio"]#green { + --radio-color: green; +} + +.color-picker input[type="radio"]#dark { + --radio-color: #232323; +} + +.pink { + --colour-1: #ffffff; + --colour-2: #000000; + --colour-3: #000000; + --colour-4: #000000; + --colour-5: #000000; + --colour-6: #000000; + + --accent: #ffffff; + --blur-bg: #98989866; + --blur-border: #00000040; + --user-input: #000000; + --conversations: #000000; +} + +.blue { + --colour-1: hsl(209 50% 90%); + --clr-card-bg: hsl(209 50% 100%); + --colour-3: hsl(209 50% 15%); + --conversations: hsl(209 50% 25%); +} + +.green { + --colour-1: hsl(109 50% 90%); + --clr-card-bg: hsl(109 50% 100%); + --colour-3: hsl(109 50% 15%); + --conversations: hsl(109 50% 25%); +} + +.dark { + --colour-1: hsl(209 50% 10%); + --clr-card-bg: hsl(209 50% 5%); + --colour-3: hsl(209 50% 90%); + --conversations: hsl(209 50% 80%); +} + +:root:has(#pink:checked) { + --colour-1: #ffffff; + --colour-2: #000000; + --colour-3: #000000; + --colour-4: #000000; + --colour-5: #000000; + --colour-6: #000000; + + --accent: #ffffff; + --blur-bg: #98989866; + --blur-border: #00000040; + --user-input: #000000; + --conversations: #000000; +} + +:root:has(#blue:checked) { + --colour-1: hsl(209 50% 90%); + --clr-card-bg: hsl(209 50% 100%); + --colour-3: hsl(209 50% 15%); + --conversations: hsl(209 50% 25%); +} + +:root:has(#green:checked) { + --colour-1: hsl(109 50% 90%); + --clr-card-bg: hsl(109 50% 100%); + --colour-3: hsl(109 50% 15%); + --conversations: hsl(109 50% 25%); +} + +:root:has(#dark:checked) { + --colour-1: hsl(209 50% 10%); + --clr-card-bg: hsl(209 50% 5%); + --colour-3: hsl(209 50% 90%); + --conversations: hsl(209 50% 80%); +} + +#send-button { + border: 1px dashed #e4d4ffa6; + border-radius: 4px; + cursor: pointer; + padding-left: 8px; + padding-right: 5px; + padding-top: 2px; + padding-bottom: 2px; + top: 20px; + left: 8px; +} + +#send-button:hover { + border: 1px solid #e4d4ffc9; +} \ No newline at end of file diff --git a/g4f/gui/client/html/index.html b/g4f/gui/client/html/index.html new file mode 100644 index 00000000..3acde2df --- /dev/null +++ b/g4f/gui/client/html/index.html @@ -0,0 +1,161 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + +SdtMb7qe*N>>{fS#>;;v8(n+Qb?W9IU_r9oYH|HV?b@cBa+rep$`n zJh8?y?74G(a|cCa6eh9|=S*goe%G7ao$I?qIFVNb-~P>fON*%tE}@=R`OX8Ah?@76eZ5 zkK|@FLGEzAm6Z@UKm6WrsdgZF*YC${5E7?w?YR1>l^2AVE-Y}0dnD)K+u?ToAuwzX z8iZ40Kg+9GzhEPca&TztX{RiyT=&?jGFZL!i}O>OPxWR&{ipj)L{FiEWTLnD(f2WM zDI%gF@9U&6P&9oaIVLw(`c?hM*>6wmGJNGNV1IYDwc&^GazBKvBETebRXmWm7~>Z3 z#!Z#m@MEp^4-9Z?w8-sDkpw>cYNa?$;791kfd1~WMdyO0-O^ANP^s0MJ4-eDP(E2G zdywHam~4_+$@gp?bizjZ)yCM2*TmhCBz_xs>Wf%-n0xQr%h>Fv8B4ChV3XEH00AG7 zwl8 PMygx@unfY&)6>U z4mG~&y?q$MmSlb4_O -QU#$zyU7K>N4`sSYdXRl(QymNkW0AbWhe $#e0$QHM3~9dt*lsf-|}%N_&J74@5|SI^f6#i5>V5$$8$AB%+Cfr zjI9ZSk9-B{oRQgH5pp2|hNkd!l+pw=nb;_`CXjrkNQ-g`jyrj|`IYk(rnxfwrWOIu z&lBLpwdJGd$qyLtTd|x2q?@!TW{lT=4myheWpqWIfbC|!lUU@Uuq8_Rq}rtQvgD%U zj^k;4-)71YUnK73S+3N6hn_du#I@=Ne-qzrwEGUwuQ%nyM2KA|?8t{!FL1hhWt{=b zzd0A((g!KiY*TAdL4Mn(;AFR1Lb9U37f~!;J1o+Az~)EtQo@>}>9cq*{{R;Y7W~R* z!-wuK3@lV%vLo76uQ>&EAiewlHaS`7srU%IxI~Y2ek*mX)i59i_Wp_Qb8pzNmR--b z55)r1A==+576F?C<(5BJ3H*(DP?-I}h*wMqOx)O;#A|v1MxX#LPhNi+`-+1DV*VZf zfb+kVL%<`SPb{x6#l3#3bBeGt)tGf$V1Vrr3c|{LJJGt-Asw)HU-(`NsYJ2qJ(%n1 zmOcWPFwUqBDodw$4(?VsI{2-w&Wqkyw^mJG+7!KdR2clOZk^XtXiGh s;cfo*?AQ9CN>ai*ypC2JHhs*A{T &u*^TC|7@PbKgtp zK0E?&`9*ln#)SL^gi8e2!|84*qBG5W$9
hZz?4mD-BpQ>p4f9;C3W1U6t<29$ o)S1I1bb-IAH z2q234NGPHr#D~B{37D5XHG%x71#!-F#^?UdZZQZ8rlBV@)GaOY?(2jxA)wJA^`@Xc z%EvAhNq)S2NnG^^Ym-q9H?4#MT)#mPyK-tH;@R^+ P6?NqZ0rG4lFJ zKH%2?quVrJ*vZRhGkimT`muoekG7dK@Ns@!Z+G?KvU}Id?-H43iE`WQJuO9!1{D8V z#}`Tz930mhb)xfq<7AMyXq4>*oxL%|6p65-*c|ZcmiUB J;^+qQ$VH>A3LRc^|bOqSqF`+eQJKue$+l$4=<^80%(7)VHQVTyix7 z9*7JD$ZXq+Y`Z*4%O!`&IeIz*6zhz=H&9{En&it$IHNT25Y7(PaRu>+!mGhasOH_K zn$VIas7*7=_x!J6P3aFj8aKRA#O2VeyNxKK<>^EDnJdT1zO=Bg@{%4mxoyf>dDbL` zH|I9XE$9{=LKO1_N~j4}oq9D*MQ-{ofBZZL-pSLNZN4BbRbPy`W`rDlL @c4&U{O)J{v8AEsCYXqxdZ@vHn4Y0DH1O~{(kx)ee_q+TU_i0VD!De2z%C<3~N0Y zY^K4dYIbtJ^Qt;EXiT*zdDGY?nU&1Y!_c+E#!Nr!U<8RWvB`=R2MV+rm}1cOJqTHA z`2NF1oD2~wcZ-)k+QVg1srU%9(CCUexIEb3oxD5x^Dv0f0bS@~tht9OS)Cx(on^nl zg8ErE_TF1g>*eV7(<^;24C~`qriG_<0FYt@8R+7MKcXTd&61P7Z$%#f+577`_vBCI zUzdUK!LUQ;t(|$vv41ONyCpM*D6XXz_c|0_$onu>5#CF72O;c(V33^DnmB~t4Acci z^S3Oe_wVeULFC=U+r(EFJcJRe&ze@rKMTw&X%H|XQq_tDl!Qo_Y-RYp7Y yY^7{4F@-%!;k{#W){ zi>&@3!9$C9)DwDw#1%H_6GEg859s$cy|9Z1di}S)cg^qJ!QImV&8V)g`tt?)6mM*I z4=D750gEYHb8X^qsXDok;9JaxNVvt> {geyjp6D^^8~yq$MHK<;U&v;eEA@a yNr?-)nJU_{ckDcr?f zuNu_J%hM(Xy%>;`-LsE1|GS84JljIxH>3nxZ_d4~RoxqeK;Rf71dCk}L*@uPL0= GxyNhks_!}DE%}}@uZh%YV}8Sod<<(C|O9BY0dKLg$LmI zwYCm!Rg(jZ^Zw}^vVsYh3fC9jMoRzvliES>h?;MwmfDVdxBLdzZ7=zpn?e!KMXYZf zMaJ>B^k2}r`~q~Px*R6s{zhQn-2blA?4O@LJ%qm^p-qm~nWZ2wT=&fsE4&^S zhAz)wPQ(Ss&3~Pp$Q+5?&E$jnjc*fne|{Z^T)V{e`0L8iSp~bqF@vE;DY!Y67#kN> zsTz(sO3_stNh%H}^TAYN9zL7yXfu254GHya+ZC55H?f^x!yo_lg>5Lz>8X43DYjc5 zPCw-AQ)r9+U~xgmclrWWOiP21-4(}Ym)80-i~Mqf;{E_1q#d&O$K;J0C`6%t$YkDQ z?m|bbnjX7KHxo7XMV%11HBWf4OF*vkKE$gT^ox6}TpgYM B zb* S+z5cRs?>>ZSMN^us(;6d+>mJXsOQ>bvq3U1l|Jh`S+%UomS{{L=mcX cIWk8O2wZx!t>n%<&DkoDwk%Ngh0JZX!u@& $fH2zl&rk7!(Dg1CkB>)9K+BjQ785UL>koxW6yOF6fQEFakd-D(ww9G->T! zgi2(RJC xh+etBL3 zp64O-80>@nzJ>2i6rGIAnI&W*$u--gRQ`q@pP7B&3+f*-foH CgTDxi
GjqwW=zXvxmYLO!;wc`Emi924M5uL(d zb-^Mi4{^Xpr15|EbO~>uoRwA^uao z-$A7dzKE7azirtel+An<23GBR35&a%Y{kC?u ^c=#(xu4c>_Wy~4#^>J>SXm*G zye{PcC$Ji_2vXs5z0@FYacF;?Y(Gf%;Mm+Msr@RFd_+tfC$N2b9|nbSH6`o!s`#|^ zsBf&^!9YYeq8k5@?Vk3CI0h(eb+^sxyB)Cn4n~o#!>6y^-WQ+WKLA~onxi_W*1vnH znvV p*#FedcxV73LYT7SG9nWT2~ zi^bc0>>Czy7dQEuaLW|& U~JIG+PzvOT{jFy8Adk)# ZkbGmNXd!gv)C$t>Ek=aHlcR0b?& z?vdufNh Jg`)l>Dhz~4 zy!(3H|G;oU=-B&91eUH(NFw*L Z^7!_QF^#?_Ks)To8V76h--R9)o DdT{cQFJx62SG%t&BucAnL1vSM z`0xeziq^xvKhClz)k3!7CzO*@UmtAjrf!J#un-N934#d~^m~noA{c5BZs92h_-RSJ z2Nh#wKP@!5Qi*G1RSc2{I6B@5!$kKWyH(J;e{$2uM0>VTPP=|%AiA@Y&5>SW!#83h zsL_kmf#y?t(0li=1}jAD10_)`tNRwAJv4fF>T7wQ+l*Es1{}C<`WSB2W!r0&$iUHS zQp#cyS-=%px0?)vQdc$VT+!%;w7CH8!dxVowA~ZXanzqyYx@A6huU@mEpl=>YZMMz zhl=M!SdqyaH^1#YEjY`n=QgQsi!i$bSdrQr^mwXnNQ ^+neWp6>EWDI{d|R&kist#IenQj{bvVarG&uP26CRZyxj! zjd9-(LL118w;zPpq|T}7!=gAs?m&9wPJ x;RG2xieC)R?8PV_@r2fDN nuJNIt_^h30=sJcG(jn+`ZvU&;oOQFvAIk+!9O2&HIZ>f@Of)oXsf8VZ*sK`f7jI2BJuC@g&aGZ8nzj8{ zp+x$zw5@RcQYV!Ch&~X01|lZ=?jL5%3{A|1+x|MOLfNbcDohWFT7!)bhSqf>eGFDh zKPPFUs1_^od?w&gCsk*z@SUeN!J5}G7U0j~lip46Q^lsu)*SrJu>>OX#GxcM8}t5B z)tADe_#$y9 d9Lf)0QEzvkiNwKOqs^L~WlWOx~F)arisR(Zh%u z2#aHJpCrT6bq+w;2uUp*jb0x$-eFnc<-hQefa^#7XyX5SEdoCXsn-Q^F1Jyxb$9Kk z0WQ{<__g-%btF#3A)1&{z5o7%3pu&nYoP<)x
(n1VsW^2EH zIG!3(P}=*+l}56)xe|)VKcItLCN||zc?o94XA#tiC}Q}wv)e6E)d}$AF*b;gDt=8U zrPr~8V=9anvh(JJvIT0F@|AEBK Ey&V8f6zv1KNBVTjXZ;|{l&>B_{Iqn`8(YlgCLR2`KbP` zOgZBOpWb12*(jUO
l(-ie=20hCO-`UED$7;e@L&!`EC;#hQ4bRZDo=ZO|kp?|$Ea5VD6u*bwE~ z3oJ1-;(pLMSWZbS_>w{A$+n|9z^FB=k;Jx?AB@7`S)tEsrZ;zdo}q}S4Dx&UA0iqC z6idLoEgJQRl@3b0OSQU5EmL?&VcpEMzLMEtIu#L#TS(oWS2!e2CUjU}AZZW|qWBBA z!14zu7>TMwj@+*BABz(!CEhK9OF&v&>?tyE5UCKBJGke4a$;nT+K UMb4!kttYHsml^T~c5m zxc&b<&m-ly*HCgj82?uABQUk`12%di*%2AHUtlB>fab27(qTkGO6^xRx}d4bR2yts z+C2Q?f}0InVtVtdHV~PVJNc0I=KtOe)@**iApv1840c0xaE8=FT!~00O~D#}gj}CC z{qE&epaVqaaE8L$j+}J#-E|s!8PoxBy!d*UY498A0Oi2Tma_0eO)}oKNjmKt@p_O2 zFOpsq@3>>?Kh`yndIrujPk1}^M@*YNq0vw0J{6M(hqvn(#R6qQ`C8*}{D2h}1PjL& z0Uer=B{atw>_uqwuW46MtC22np0>G~l6fppbCY=M_6h$J#<$2sq|LB8whwhz2WSmN z2pVH!h7$ZFd7*Ar{5y5KUp1awP&N>^V_O@WpAsUqpBFUFdkC`=0!b}iZIkL2$AC}o z3qK5daC@}Hiet^_5xqSDVqw)sn}ljLGU9+l!?)5e1srI#5$`8ZrfHI(cP2oG(chy- z;-176< )1PGeldkHdMXyXFr3 z>bQB-I<|L0o*iLUP8odrcm=`f74aSbWGMA_0gw>#E|xsKE7aFla34jyl5w{(#`9L= zyGM~J+Qhh8DT0E#G?dMfw|LFz2|h?IztNTz8{?RAjp@4t62}$So#M1XQ|&y#;63VH z?vQtp8-9Z67-_=PFM`CmKIKkn(x_w1G)VFh#WiKUa-nmDQJdg-C5Npvd*5;gT`X#J z`f^XQ1VVXN>#)MJZWK{+O5A>pS`wCeh_RqSZ?Sw&5{HLYGvr@|?--O U-3Wh*BNy|!$eZ9v<6CKRxLI@ zm3%){tvgvI_Lr8F;XT-{PsNKm$!K6%bT3|+K}wP0Z*1$9@ZJrZf?X(gqBK|P3d2S7 zx&OKpsqdCWb(cO4$7a07fzg@%=pHLHDa6F74zCqn_aG1kxxbrU<{po4lD4(G37UI8 zT$e9=#J^saB-M)5WoeocE8vMI4>L{uhLfkJSBa0X Z1jG3P5+o2#`*5ybn*s=n!ax6Z2Y~)n<+3O7=drBT}c&k^(j7G9L$M6iswx) zcJV ~BP5 zONk4qGh)phjhE!6o6BdErlLhuFAe3zmB3Zvk76caIc#bAn)WdWfA-k9+agB_qE^*i zS{+z-|7(5>*WOhTi-EyN4?kFJJR?~p39_mb+P7ViE7FwRe7|+X3v lZ2%ZphRMIpQ& z)st%8st+c|RgBG0uEYB^11t*^6Z}IFX0L^x)7HIDof+hooFu=Q6+WrCv3lE)(C_=y z!7icC@ihGO{I4J&njt-Mhba1gDAKk*Lg{Kau4Up?P5ABnYmVve)E%_rsw#0&0$B*( zLSR@iTxsM2S=qBgxocNAcvIBe@s4xlJd_`i^Im%8dh-!sYczDCjhZ<4Od?ApHy}Nf zhrM#k+(*g&*lKHI@h;TOoq$B4i&vfxjE}s|q1@UD@;~lK_)jv3jgJ2(C(Ni>C<4P) Py8>PbXFRCr$Pod xik0N%$=F@K2ILY-20w$ z{`Ws;&V8%GiYo*P(7BDFWn*X-hL&OHpKUelqM$ h z2)PwJPy){upya=^MzVs?h3NJg_Ezv04MTt(vg8RbRWMt@^BTU$M=i !{HWmV9Jp;1>YGf(A>#-=5#1^TdxhZwU^tMMsShv7b(Jc3 z4!E@`e02%x_ayZM^0tg2v=A9M2^a<(6tMvZ67+yfY9sKDg2zf=c0q;^JM9S_u^0Cb z!&G3`fRH8KrXk0XOH1ITba&vSEujn1Ej0{|SS$Ky$0KJYc?85!Gf%@bv2l+<{g%9{ z)ZLkugdUGRC UFx1nYDX?nFdrC|kNPmRQ%QXEv?8=vEi_!J;4BS|5?`*p zBLM`$3TEWM9ivcRC2(I#FHH+Vi!-DtT&Usvi1{s)Qq;0%a5;wj0Nh&&Q_{gn6KFz< zd-@0H3fu+s&K@2Ga;5X+eWe3@A7r nR^1vg|-yhWf0k-%gm zPUM;n@Ia7`Ab}yYc=|Nlp`73$$@H)id;}ztPu%DugJQQ11fj>HyM THMx6;6$7wMwj$^j&{a^KqMCXI}PK?oVbvbrH7@A(8JI >rfLSwBlrfVMLf?vRy$LSWa3#<@{hy; qsozRofZA%?X z#?b70j&{XS2+R(_$kC`}exl+lp(Ca_NsW@QPb(II>7_8zPdl}5gf2k0ZVcBe$C}~W zIF=)6g@9IYM;=`3SG1llM3bGlCydkZe?V?pL2f7OHv$z3uAdJ#_+ipBPH3?+H-=#f z?zK)6zqygN`lW=zd8P2U>EnlSLQg=Spd9m@l$*6;5r~I?WR;&c2KAh>Q|?61rQt z6PUl7$w^vW8H>PoVK{!A!6aN`gpO1$nx){Vbg$%@vGfV%!sbY|D^u~*MhG2AW_<`a zIhdH)Sp^vZ4G(vMGfiZ^7$I~a`fTk4=-W(_ATuYpbK4;GR>q?4^EyS(guW5oHpi(R zpDi_)y<%?fkBxxjDE7=p{ptlEPlS%dHNT{xmzPP{do2PH1U_sAM|&ypn>3*#=jO4% zb+*)iC8Qw)Bz5bWj!>BFc{*uA7ovC9Fc)ZRXfaleML=RCq?O&_V^Civ14mMXmRfU7 z;ALB$D;db`JuVQKR|*4?sil_`p(mop025qH%wA# f=HV*ZHTQ#l;EwLJr29AfhRc^1d2zW(6!8^c!eAIe3x?B@_ z0(yjk`+=rz6x(Yo0)`MM1 KK3&5DK2O%Fw+OgF;DRwIDOeO&>LhfeanDTP&u&Ju*H{F6MnK- KSV^F6iOz27IuH{Z9 zN|Oedq#eQ{;1+>R3cAOO@rb)aM`AV-@}s+*k-g3$-~|B%Q}R(4$I=m#(1qys8eReR z^fIu$*COB(0$(cVpO0EnQ-4fC7oq!Wn5Aw16Q7=kRqGLfVyQJg1|>-*)g;~yJypX< zkAvFVEdstFpkP`)N-EpdP3TB^)k0gAz_({%6`Mg|X({YhGfk`34qb@;n}$csjA^x4 z1pGrl!%1UNPehMUjnI+O1oAT2&%bF{%@zS;2)x!2`bU>Ms7B}s=*|k>2evUbq*Y`Q z@DG92A?P(4^ {#A?6kw)^96kHbMa=1Bp zkk>Mj)u>_f1}HBBq|Kw1tU^G6mLj30Fsdr}f6ESiJGybP<4id`m8hs3ko1^F&0yQT zV5dW1`|hyKZqRC1$lI#+>^2v}nr~tCxA4omu;eZH?I)-xbN;mC4_nDp1m0{0{Vzeu zw)RIEgGh7C?}4pTvGS(d!k-R v-2m!{`>)0FcmgS+nqR)+YGL# uOl|boKXy zY$G(VvJ~3Mi(w_9i_o3IAm?X)MZvavz_I^=?e_6^C^y=RSHi48u zV~37jn;bn}yA-~B#CZW0$wER)UAo=G9$iW3iD=16spdj-Lx@DL>2M4TxEEUPl<1xQ zUB7M-yl^V~A_dOskR1<(VJ|2DqUzrYKz?!Fz6L(L**R-xBcXv2((|yA(1qw5H2C^n z+_F6kf7!8K1WkT@A0Fuqx+4C}b~+S>y$Fq41#R}ud}ODdIS789o1KJKFd-i`PDQFB zJ?LjkHl^T@YoYhG!6bvsYVJ6AzmAI6JNJd5&q3oDcJQFAYSowUXdlPi7j!F!$(OHuC hXSpy%D| z;k}93M`$S*7KRhl4d_2L0_kMs%VA*aE^y)t&?ex`lEvHjWPe!lc5Ie)8VJWd35}Zj zz(Rv6*M1LA9s}o#IWNFsdWY8VSz{Qe#-qE2;0>UiAM5Y^PdH?p<6R4~$jj8fFNDwT zjXldQ$HU-99hbZpk#qXuIZ(U`@|r`dU0|C%A=i*YNzT$Qodw7F{)+Df1;@E%$__0v zQLrorj!+ZOJrukP !I{F=WRZe3o?dRl2y&+{UUg4 zjN_fFDP4!dpa-2e6E7m}>$~@;ZYGpqtG&;JL#~2m+k4UO-1~kZ9Gvf6kDnS$6B;ND z!J%p*dH`U+t6qEga&F%DTywB2dckq~F8|meb>o)MX)yGgZ02nH%}mFHS7pzQp81}q zI3`Dl_VXeuzkvJpj;&$4y W{bJM;w#?li5s zRYy2;fjKkRl6mlWzu08!D?8F??<-ig0RGk22?(kw` 1))O1v1hT#|7q#|fbNX F2Ll*)D=uln#UT4678QuvX zT1!^J0|&tGQcyL9NCezp-*Cc9V~Iq{iRrLT(XezrJbq+sLhpAW9DRrPcYzh3!u{Rj z&t$g~VDQ7 fSHP^lIFWQIk|H6r*q~1{IRQD_ z_PZT~1SVwRGw|F9sMr)=TZ^5XBS 1sq}ECvw3Qm=m*zm4npoC&FJI^0q^-{u=J-<_>w; zq2*c0%e7ZYHKBo*h0u}|dyv<~MBgtVmgg>nW(Gi#U0KXfUp;DahKcJscntJ4&^z~y zQBKT7JUO%g4!y?PFTpS3%J1cFjg>)H5*BM9lrz Y z4*RFO_1AUP3#Y-C568YjHh?o0K+8XQ8%HAV#9HG e53)lqHSJXC zI?VB^nUGEEVdg*(D@T>c8CcG ;~B30B M5_ZEZ 6AYy=j;?IsLs!GI~G5p{DxYK2ap5DnJcQm2<+z7qKdS8%u zBR{#z(IYl(dCxd-H0*k$nOGP3Vm> B7tyzrbz$@X1A`>eztD|%+%)1sAOshL5GTx}2kA)MSH8ZCG5PF#qT5=mY znpu*gMQo|3MVZ;W=$1^9XHJA4qPl5FqOG4h^eruFS0?Il2^@8+HxHf{9Ae!ocJ|jV zgO8^tM`qF4^&~iMOYKf?GfXw16?`Y2!uK>B>}@I4@0LK93x9&V7T&c=Z1Rg|!q-ut zi@9#dY}lcvcm1(6+}zYjG>sN1Ro3q|@6mQ9W-N{%3Df-GCiqqwS9_3s&V~W^cu){^ zYpMwid>}it1oumjzcCR{-YM^Z1gv`%aaX@}6}&(354W~N&q)lzeo<|W#Iq+}zqb3s zPA=mZ;?1p4jF>gt ZH@ck+1Mf5Ao-SPj?_3{MGC^`B ziyiNt9Ca#6L3U$Vcj@XlK~>2wvD%%zCA!a0y_5hDy2!T_teuZ=$`_c3;*uvIu@w&= zQp4d9 o?1cDKbcemeR(1NbfTPl43$H3rnGyThKd|!AlB!sn{&0HL087HT~ZJ z-mX-v`Wo(yk&m~_5is-_GvS`U{|pc8?>@xS)x?v$Nb2?NHZ;kbYuuJfLM!-Uvm7}l zptlaeQyPviv#jb`B*at7(29LH9VA}e43p(_<(w|XW~AVHszqvEcdR1|J(2mPlF-0^ zN~Kt1q@1o~xf%N5sSQELflk%_AeW-8nsq!v?{E+df5lKTsU>tG-xIgjK2{2+R~0-T zufafqQJk?AZ1J=Oyl7)QLQA^8B$Jw`Um@l?DKp@u&79k(T;Fw>vO_DlF&}kxgSDg( z>wp;W5BLX!0!-?7gqDD)lixHGgDtl1yLWd?kExbSA#}Bt6h-JRVOZ!lxKg!9LQ9Xl z*^K$ikNL(U^wzt LTIr^r&= ctK4_s?2sVTO&*J`pxj21_N~{6N5)w*J7vM k zRZZ=sH=%T4mA^F$od)+(S-&okdVObq0WEe+Y;Co!*0B6jry5icjvQirl6rbI@s<#S zn$=z<#8qO^D@*jo5b577<#c6pXh2z;2c2s*ufHALxENjmJcRamUxvImN(1{gU7$mM z5OZ0({b8$}6DzhL75?QXef3wc@^e`A6-ZT1u`EdHl02-+I(D(@-Njgj6o!#wht~jq zv2aMNb7fI=mt%WJHNFN}SF`Q@cuAMJZOPWDF+bT5B%DElz@)CA^oWVB=3Z!`373om)GjEs2&@i4FKJpIlh9A1bAE8n(fv|8PdmCrz!d_ob%g%I zQCqsS*Q#kZ0X;&&mMz?sT6>X2AO#30I3*udt+zuhLKmQ0G;!SEhAgfrSg9Q{8xUAp z3cD4csx{$@S#`7!Jyk >}3ek6H_v(30;IfH0+$E4HU)=0vvV@X^w!r4ED=MMfF5;@lsfI$wYK3;3?p!GzY>? zKQj<`wHXY%1SP#SV@kc e(I`xex(JIku-CA3^rgdV8jIf?I1ODOE5(;b1Zf+6{+=jvOCD?&@~e^YqP zuX17aP11gz^$5IG3P%;7B*&;uaYbm+FcB>o;rIGccDKGs+Rw8Zff5a8jzvA;1_jrI zE=0EkUe<7^8^!h-i+~9P6uhlr@EFu@ZuGe(v?v>oJ}Ac-pphHp_8N (fR6}#p9{y0 zLVcCU7zq sG%e}A-8-St?8O!VcL>ZYg#k6w ztK8h06rm$$={*&^sbO0;1KDdV0xl6)uApx|>RXrBSGz1}LPts- z4fAc;gJd6py)S~m(hAt`DwL;29i9m-lbL`%OTle65x|l&Ndz`Xk c)NGAYkvn-^RrUh0k0yPoXsNw7~m|0bM-xNf~2`v*FhR*2;S8KQio3>@@ zS!Ifzas~gK594P>)pa(tI9~`Yle-n&dJ|ly;bOPBi>4N3^#m3H>4`G646Z5g;5=#2 zGj#M|k>kfSKuRH4u?S562rlwtXRd !!iP|IylLd&AWq_;mzR&W83+fWO& z<1{D&6$+-7z~!dx%=N9J!3ixBDnPex3KwgT1Oe-OsqZPJ*XL65_NF|z%}ZQ!vP(`0 zp`&){6Q#WX&^p-#*!u#7fE0rn`4K$fr)jRP6{n2Qk)1l!7=|bqub_)=;4^)osF41X zk@mz_m%^-uK4wHimr_DkO=J?fTe*`UU|TY$C$Z;*;j(cF*3j@{sevH0EG!aFEe@Dt zZRU#~kJ=ZV8#K&TaIvX)X0Njh454KqlKHY2&d^RKxoyqt_38S1|56QCcY+5^WSW?o zYM=;RwWu4>ZF6C^hJ$R01XGXNm>wxLFh5d&{8wXI4JisFp=E6ntyktW{*=GAhSqD< zctAkGDh; piGT*{x|y=&18`Zc~sxisEUs%|Vl+(vKmy zs2E;JrQ15WsaL-%?Fk)4?5&!@5Dn6PPC9kjD89NGvH_4Ig;cwGJSd(%ucXcxLRSGH zC4Nhw8*sUH+~`fbf|OzRZxW|$2<{5Q7nwrjs%MmOgpMZPBy`sbxKzVo3U<}myK5Im z%x`Z1)6&Umk?3ZU(S(k&inLd-mo#wHPWE}W#EC3bP6)vZ3O>(AElHFh>2`fq5IXvy zh?Ax%9H-$7U_XiMQ;?VLvDlGHo^qU!v+>7bttf*R)4>^H@=KF-gsuWFQq#JFa%|aR z*A{Z`3v6u?V83-KSfk-HA#n))D}h71!Vf`qPy2~U))KnLt{rLvjmn{U1@sNW31Z_0 zw(%2u54u-|V2*-WIWRXDHm-rq>27lKfX9|wEurI}C}qr=L5DE(P_U1N4nR8v+ecd2 zwE^->JcJlJ#9Oy63@bvgT7$GYTdd)e5PVz=i!6C#BX0@ql92^yDY?)h7g~m(xpMx5 z+`Fg<*&{ppwhG#4Xc@7Eiw9HO^MZ8=jz><;xg`o#XjmJ9m0?(>oj{ Px$tw}^dR5(wq(?3YmVI0Tt*CTo+86>o{2}w&0QqT|*(jSTlqCIG-vxZ0_vmvN9 zH3(}+?{sQvX)6dyi)xV|Y`7tZFajkg0?9%z?}^{<&N>e+gnG8;c|PAapYQX0KS9kJ z5<4S3k^N||T+cQzf&67*y1FE+Zf=P!%iP9k{64SY$G}( AA$4zu2zFjScKd0C!8AOH|EmG;UyVetlj7qhUaN zhwWWA*n5@G!0ZHX$2fkU;v&WG%)e&a(Ldmkb{0OENdQYttunn|nSH{iY1%sY_>x0+ zc-~L Px&%Sl8*R9HvNmwilCWf;JJ?}fuxMixl9A 8A3fQ~#*>m46r-YuR*u=UlB-QyPw})lz{Vt+-1 (JY_;nJuo;;m;M*~9 z?)KRg0a<01NDKhDa(+HkVGkBPl@1M_ao5BEKn=3ifcHWi_JHOD)K?&!zMKH+s2T9n zD5`y=-0F0ssUzwHs7CIQP&iU6qmdV|w*pZlREKlG^$|3g(fGCMI$~h5s71co4+nj% zY7ansI%qM_^E-5336)=u9UHtRs*$@T6uGxW802h%jMWex?Gd*B3@3`<+IO(@Q+WIp zZ=n9W&~^q+z7544!C^mH0G;2M?*;5u02d@=x>e>@ngD@TPX~OM1O-PS 8eyfY$?6U`Qw&jYkXz>gY1$5dd=Kqk!fpEifL&}s>Oi>Kikk^V>M*+2 z=lL*wF~lZ;p@Y$9I?VeBrYtape%udI!mKyVXO*hGY4Bhoykkkl7t7$+M!(4Pc>% >YX@verXVj(?a{9elO~+D^km$*}6GM 1kfg! z8hS4{{`LnDHi(@HMn7oLaI+KiTi$ZcMl|lNSTT+3&qx7``|sElg*pl4!RtSCZ){Mv z4zX5QynjYAMWe>?|HgPIm5^l}&+o6X+?{1Lp4&ovG0`C3I*z-24SF@}gAE3hj$&BV z1? <-wYx zi3b&hYIDt8k1N^c{`LF)|NQa&zW)3C{eFmcL`jMr7ZVT=khHZq@ABKJ|D6cn_ZJO= z*!(6DeGy~*+k=CHxVShPjYc34cs!nmhX(`#v9`A6a=F{v+dqH)q|@o+ lB}#O z3WW*}4>vbA*U`}dfj}A>8j6aFa5$WqJme@KAcnU+e-0B fIFnaVEJP26h8pVU>iKD`!i{BV%ZX?fW6 zdgUn}_)rxuxIL)GYQysNapD%6`)i{g4;&MPkN14n*(t%BelqkP5Pta~?CT9>!OGxV z%SrQzX;w%x+rp(A5s-ZSx%*i7I1M0sWb_BB&z;$O^#!7(&z}KId$ta^_2_*J?p-6& zqaWWYWbvh2CLf>pAA8-_ChVgUfCXaLG7LL`pm8RRr()Sa3J0^d!HX&t&rR^;Xcw39 zfb+V(4;(&+{!%{}D|FQ`f-c`%gUTYDKWds^C+h`CtTrox)_KkTV$g=%V7uJ{*3bb& z!qk42>bCEaQ>~IVY%)z;ePgxL3<`K&>Gjn`#}1R{sQDN=3jx^6Ybsbt>?Gw}m)YIZ zRm(b372NEnHW>xD-63tI{(N0)<9j=ZE4${9o;RIfs|pU#GRf$kn9D6*jr;qD=8Lvk zv0kO_ZD`h%ksL!o{b=+_=7Bv5(LoV6ZvfazJft1`eb5Y$6g>N9RTIp*^WN^C1aF0n z`IQ+r7x0mBk-_^;QN_SiL*i$7nWWM&K{~o<7@E3lh~}2$l=fxvcm9@=?yQLq=3ICa z-X#3P{Ip7TZ)VH@S?S#+cE3}Nm4mNH#QW$GGT5-e4gBHWOo*2>RpAWpW`Ax~GMTHY zAu18rv`Q^_rBzY&pf?m+hz00!l4Sh(3ye!f8%~i%F+%gguV3{q2HTol*3o*O*`KM~ zYL~8>4bfY)IA<)4IAtj@I)Z}i-#46F88Jwb$2Kt(>RsxjyF|avQh~?Bhy1cA+1Tty zVky_?7Gm&j{_TB@%hdl&8EKcXz?YoF>Dtf}Blf-`t)W^6h12D$2grqbYP|B0aWyPK zg`@Ckxu6T?{lKG1dO=I*pY*dv94%!Hc~ hRt9&~KJLm;HtFe>7#0J^ z!CmWknS#!t>iF0x-nX|VF?S;6y w9<1>rI7Y`cZeL5yjDAk0>}=w{gFgCXsfs}-vg^p+%0JxY*Bk?^ z1L9)|Y6mcqx3b?grEr^b`A~z^O!kbXzK|0iEC#<(olu7XklL*5iZn F+hOO8e7oR%bcIebQ}(eZ6Tn ztXa0P1SAWR@2!l%s9Pl9YhsV6^Rnq52X yEUgNEc3OS7ILAWaZT&E-hL% zw{_vw@^=;2zJy6xX%_b7et8~<3@-4sj_BYk48^)B6a}LV&VkM@pX)chkA+8oJ74Hs zC9eygCRbC=FzZH#*|7WTr#nM|y>bH)E!>Xb*HP{*d35RfG2`vbNzYK-YNR>k$Y&Xr zm9SMkxz9~3WpihP3Of+W%M2Y}Dt}u w zhCbjqyTE61y44Wpt1we|T>Yx^R599V{-;#MiF>J;WO;mrPX0XW(4iJAZUY!+N=wgP z-i#?i 5^YjO?p}+mA;JZ38{Zh$X@gc@6B~P-bI^_&b 8eeTzhxZATDO&)5l` zkgu2i&aC6G*K`MCLci`4q&ADu0PLzVh(vguc8cr>VNu?fmu04sXv68ZZgUej>LK-A z{ GXPc#4K8K?gXlh&R!ib(wNcfoP9N&S?UT8c;4wCzl=%tYE7pPYBcHHDxMY%!p zx0=I;@0}>c28h%V*bD2C@f=O#&TK^w^3PPZ>cH-!rI~4hgx0(F?;S9I+o}l6+N*IQ zjcY%olaMd$Ab}WBR6#HT=1UOlx4{A=G9HrBDbq&K*H zHy?H%+SdDr2QX<%*6ZNNXubdSN~&2@5|Ey>XVOi~D2yEJDeYyLe5hM0(s}MCDsyvw z+tbeSo$uJ)z0KX0%i2-L6;f8(YM&}Lp%PlSCx=uauJUpN^dK|ZkL%4R#*2ggy%hgn dkyrR9y?pPIr(B$>e)q6|t+nI%I?EgQ{{pq5i6;O6 literal 0 HcmV?d00001 diff --git a/g4f/gui/client/img/site.webmanifest b/g4f/gui/client/img/site.webmanifest new file mode 100644 index 00000000..f8eab4d7 --- /dev/null +++ b/g4f/gui/client/img/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/assets/img/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/assets/img/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/g4f/gui/client/img/user.png b/g4f/gui/client/img/user.png new file mode 100644 index 0000000000000000000000000000000000000000..d1908e1d0a0f0f10cba697b674589277cce6e019 GIT binary patch literal 17004 zcmeIZby$>L*Ef953=G}f!_d;*-JMEzE8U 7|y-cZ^hnw?X~xr{G9u_1d!@zXlnovu<$|n0O02`a8W(X z(+vQ$wa);!002M$Vh9wl1Sxv(4^_?vx&|P;UA>*aD#X<}$TtAt>Fn!+a07|6+K6D3 z*wZJ-HNef$*%bkTegVF2o?fm9H18PV7~~j$aP;#7l@QLJ0nVVr#Wm2=-RI{rc9=&{ zke`g8piiKHql>STtAMkww_uo~pP;aSkRTwZ80P2be8Dvc;pFP>=_8N)*z*91@N|(! znv3fT>HDd=dU$F@1h|?;7??RnTyU0lK`JWX%Z15=dHZ?0200?ayuEw^Wy0i 1t$cA!(@uB7#=p5kb7vu?s1m)Aw$u~Gi9*I14?C0Sd -XFJKgRl7j2`hX zBW=GRXEAUPs=fiPzwN*_oY9>M3~~|tTLW#19;zS`fjDhf(={k4T-)2x-8E2CTf^+P z7tpJKJ4)t>mZ1ag?&%ivkM>=hf9v}N2Y8`db#WGS^>X!g^$7|Db%nvEFwyn%3J(0O z4UP@W2NZ<1@p5q!1RFf{eQJOjhk6(oqSJ8y$8muQf+9jfQv5<9{36o78v~u0c)EK8 z{iDVInK=Py9nk7`cx6-rTwOfDM$vIWU;-oPX&U6~d;zV5MEomaGRlF0u0h&r@?%!R+mqR6)j2=3u|6%Cp zrRe7v5a? z{~9}Hs{Wyc-gwXx`q$2b+R)G#xTAqNA^3X>1exEPsH+dSbB3a}$e%kvrO~gA2_Y&V z1W2i9>tkV|_xmJ9s1bm3nmUZoFu?Nv+DtP-eE{13wjzO_3xFzskAs7Y1INe3#U;SU zCm^OJB_<*wW}>1dqh({^U`MhbSvh$n1vz=dcvz7_%EDsOvI+_c90F?Es&ZPA@(Qvj zClGuB0%9U!Mp9BnS#Bh^?EmNTa{wU2g}OjpU=T6@N(O jh@7M*#SLL&$8HxHIG6AH z7XIhx5#l MBrR=4>g~BvW%*0VGZ44NH{%Z9+@sRDa)rfya?+7`BcQGPASVA!(Md z%5Am5DgQ@-lp1TT!h-o-P6{wMJmoC!R }rDx3|`RgwH)fS}OC=Hvz zbK>bgH1P|KjSIuIm;SP5=D Zq1_Eu0lR|&Kp!m^AZzRSOPnE6uO#ufC10E@zddoNSjL`hC zYHk3lKLGROQ!o0AMo8GM(>G*JQT*xdbLsLGUoIUHwD>|!ESVA*<5rtd)Fm|lnB%LY zB5kA5G D-!YC_yQ^5%?Id%Z|w}K z2FrDWXjFysFrR*l{U!oMg9X3Ezg&MI tm^EW|B`ZBA>r@q*VNMw=hDpKjqKRot zcL~ZZqfrXbf^(EXhYP2=RM6UrD)wkJr^@&}3Qb_O2C*T~R2ix6;pXt^&I2^%1k(%_ zqXiI4p443wMRd6C)`ubhVh<02`5-h1a%{wY<+FJh4%%yyKL%n@TS2!zum&?lG`ER; z-X6mMK;P SPsq+zS$YR0heGPnkP zB3H|OJqoxI2BO@ruPCeRJXMD_nM<44iU*s^dUa^~mhH-y6EvxXS~)_;n?W2CQ#d zPR~%)WdXBR0U%X+Bo*K8R0;rr1FTUuc_jN#+OV-WR@{oSN`RYIWxw3% 3HHSe&`= z4g>3QOus= @Vpl=}BdB z|5tWH5P4abp8QW8;6m>HeNDkWwB(caz<@4`(tpqbh)ft$+0rP6m4HZzETwFY6jj83 zQUfs-5;mIyxMp25dMExbO8*Q0I|4Z1RX!gn0EI$eFc=mD8*{l2Qc!GwREeBIh>X&R z3Lz|pWMyL)$#4KK{&B%u0thzrCs1kb0-M<%F+VqMYI;MUMr8bc(`(ePdA33<(p L^N5Q|lr*0&nrEg HBj0#@Z2!S4RXzq{ zg7xDL)lc;&xzC#tYL6ckk>Bxre#iTT(b&jw42iKtqu+P|?UYpPHB$ Z8WjPn_#} zFG18*ji-I8IxKJ08!=xcSPJkB;k|P~vK9BN)i E_vOaJqex{0fzFUEDuDjcY7zBE4ds$0%I z;V)UZCAuY}e>q@GO)dPYf0M+%tMen|D@k1*(_N9RP*?|3dR#!D<|gM{!q*EY*Uw)` zNz@va>)bA>DR$x~f-SVvTY38B5i-l)qO42dl*p$n+9R_%(K{cl*Ak+;HY7i@HWpWV z(NTX>LBV3N{nJ3wNqB48=cj!s1vyrqbx-u9guE@Q?p%{}9anI @k5|jZQUB{)!MFGn4ivmvdT#AbNJbh8c-ZRhByySbp7Wiz_7eJXWB>Ic z<-O|9%gcE0y&`8M2Hs2-3s`;U-ifa%mFr?SWE~u`ulflHZ!9RZd|tnpdgJb=PeU)N zNCccB$yV4D(ob4*H!iE*RhH`N`tfPxMU|m|`(bBF)W;j*_8J|8M>r{kB?lpu5vHTL zw@n!Jydz2u+}TdHbG}p!j{f-3@Z+@`&!T-w0!st4*V (?m6SysL1Hc74@#u{f> zI`8^z9-2P8QSx!SF{oj1-2BUSLU-oDJJZi91&1XH^3ooY%$aMW3o|>KN7o qdcX$f_Uwn;+txNVX)==wxQ46!7wJql51V)18Zv8CvX Opz=K`74-gS~l@0O(PuECZBeFJ5kt wCAU%Ki`Z@5Uk?I^-5k>kU>9 ziaogEhGZBW3J$R8SZc@=nYZj0w`aC&+W0gmxPZgUcQ=T^+4|F1m_gqQhHII1D<+?q zGDnmzS;Fttf939N9aK9f?c1 zy6rIJU%A+%Fm~g6?Hr^H4xEPsJ`m2-ozHi%ZH=$m)bY*=e3f5FA)dpK7}KGAY}F>} zIjuJDzcEmL484-baDGu`JN1*v^gV68hRBSAY`3#coc!kdR95_+_c|W2&R>gljS%6a z=^lD1sa5q-t~n~K)dfFWRJ22qX}7UaB7S7htb`!_(Ix3V3HXYd$xi^AOd>}(Lonsu z8J(Wg<|r(J%+%`W>1(Nh)S~NU2*IbO)T-;sv^;xNxX(0NXsW9@+lFmLMbEs2J{V?F zY9n+Uk+ YW@cwwD(Cg#A^f^$-+uj6)t z*!ko48x6#VU%$%-pS8GOmvVldnL_2!8F@8z=br!!$#jS3mduxk>)`LxnMY*~=EfGc zzjK0TN=mYSKMw0dpAo_5XNnMM!~X{j=x+@fQt-_c41632heBcK(=qs}3Pwgs&WaRP zQZ}Yw6B03U^cPhzaf&I!qC^B_w!~&-^gEO 8F1%ge%VUlq6Qo6P)uuHa(~Fd|H9IUCcyz k6uf2+q8s6S^kZ;9AeDpXT~2T3$OTx z)dqMr1$#cDP7zi#xb-~M+yv!{$Cle?L|)fum1U+@>zl5#$p+43onMI#eagnV^|@n~ zPDyv!ovKnblBot;I)^E{&6%A+WCcL){_t|ZR9?A(`#N|9AZ9O@#D2$IMf!Tkt`)R9 zaVBf~hpL9x-u0*gm^3r_j2_jpoCL4fQeLA&5xGK|756iE>Qtq9n=%rXJ7sYtkh*=1 zOG{*^RE@AjJBE FJ{C<7 Ac0oaC&jT-~Xiz7c99fttzooNHRGY=3N)6A5thwQSjyX(zo5 zqRKGwnuXXLJ~iruTG?t_*hAxU0h0Sww7^j0>-C&Vs*{F(egQjSUxh<@ B!2@#GJZ^HbP7V{xFg{x*2 rFH7hy(8 zNs~R2X?ll8L}&LSJ-WUPVB 0gN%&>ai%4_%u0CGBb%k+ z+-_pr;br#rwF~$(&;)z}p84hsZYw%LMR{MH@N^;yr0w!Gjp%0YwO%urzPe_(dt1?t zI!7$?jD1U|XBIE=byhy-(97Awd{~cmzD{UyRL8*!ADBe(?jfCbT>ks3RCi;VTW_wq z#AvtEw%QTz_EIsxc$PoXk#2{kVx_|8dTnD;hrSRtu?QSaEy@NxV45dv2)Nju+Hb&H ze)hi9S%ye@eYK0PocIZ;UQ_aV)wuW4R?c&0;=q)9Io?F;>_`o8c{%oWV~=SD2QhV> zBOuEq5v2)DeQF{bTDUOQzeuCT%Ru~6P!4W#4chdKCd-v~m&?n{kIbpUQ@C3$_*>%3 z6}i?rX7 Q2|nWy^bcsniF&G?We1%*=f@Cs0$G;r*ITZ1LO! z{E!ckuEEbYn_`t`m-eJIkQ-9-ZA?AI)#kPW4+d?rzJ+>7iuEw9^dtN42FQ%8?Q~bZ zPcaJATF5ywFcQ+pw-#`cfPc2<`O -3( _QIw)U#?YcYD6HK#pcY>LYH3fQv)y)!Vq`XEPI(^h{ZvWe z<|w@U-2-t;yWYc|+Z^XmDZ|UO%uwAjC%15Jx8@eVS()9fxvz=a1U`@%{l*9!jTF6u z_Z|>PP{`JqM`mvIFM{Mp;&?)@kdRvKrjc{ZeWVrAYPOyID6Cd4AyC&n8 3J54KUuGR{7bFb8wo9xcTgrC!G 4{jmmL=+|7~JHcu1!(N9PR(4bQ^tLt42M)!zGje+DQ5Ws0 zYZlKZ7#Qey@SbbB=qmRu*h#-yt%AT%cbb6bHEmE9a-u(MuBk`rI!y04!Z4+VUtRO& z2wCwpJde_;EBZb9 AG=K5oPar>f^`s%Tb&jgG56&y$ zz)@6Y8~Qwbw~FJ6Rt!0IX ) zJ@_`-@_AHV!b#L&503bbz48>2Iut>8y9Bkyq`%AHXmqu&a)+eq;&?RMFIfd#6t^6) z@(l4Nq|PRFEy!-ry!QziOV1T4`+Q7Y(6CLdAe$YV{f>P3ttF26L1oV?ZLp#?eSxPH zoCM0r{N>tB4;(KOJnW_AHX+bc7rd+o?oF;!_o&9#M`Q9Y97>A~r6);yRKcfPiy6b< z39@s%h)J ;ENkiCMNBU5{kbJqWc>+f)!dFriKy6&-x-l@AU6(pTjH^N;Tsfo z lHmxQoSAu^Dor-3E)Y4+g%wfR2es7X`E7e zrip+4q+tII@!K5Se5`%Mg<|ckZwoY0Ro^O=DR3MJXz+3ZZ<~#MZlS~i=*W5(O0YF! zgK><$sAH46lw2+K_Xsprvg!(I!aCSC%irapo1}Gg6zkiyJ&&!WSw*=pBwJRIAyo11 zA-U$;KGyq!1NiA2{gO#?PY+|Tqy&gRa*_LG0|kBxnhq(rfo$Kzd!nOPZgf?KSLa{P zTP*#q_Q4p3)cwXJsj?I8Hv&Rq!9;?yV>=6EahW1j8^a`VQi&DOoZnj5X(&yAfptz2 z!t~x)l6EsAPNItUTBI(qOOI5yqk-r+q@?LvDnHZZV$Mkwedu`!E5mjXA$FkG? _|)m^(|-<5@(XV|=`E zV{8&i$pIYBl&;Dj&nf{(w1eP89v+3(ea1Q~`kiQ{qz}~Zn&=3c+jof_u#JqAPkdJ!s)kr~xW`J7Qesw b;k=iu*hJu-p)}6^g2CUITIaWuJ)p z8KRfw`UbgUQv>v)Ng=}-xXOOaHj>;P>4Q|#iV1hFBd)%Av?<9x$&e1Eh0gk`jktFW zeq)zvQHc;?q+QU)*@#LOh073}KUr~zc6b =6;KkV@M@py%hxs@Nb=@S(a*h|C4sjf~9&dS5bn^xL$DY;Y z;E$?}(f-fwc}Ee$U+HP`1hTu&K{{A_o `?`6YvnWnx?;@7+ik!S%bEL7nMR3qk{YH%ZE0Y(FlIl=LzZrk`KM4JN7a z!lNCmPQS9j_?WnVuOr@=eg63?hKtEP7yUGc?pFZc7n~uR)ZKSHCln=q6v4-~w^X)Y zi@*D^aO2HPN3=uJZLbR7>>HDArk|aUmkt#3R_&d=i0Q%wN`J(MoDhdfyx-jj_M>Hb znrlf5^ICa4-QB*+mEnC%xN{+HvZ?Y!!WbsT(ec<6a_a?w#Y)IBgCc?Uhube5-E}%u z@&tfI1dU6^!k4SJ4iCEHs6(*&0@YRm7TOE;?|<%kwwMNngc{~M&2$S+Cva;y{r#&K zOcF~ij|R__A^X#YX9>Itnn;$O9DTdX(L-a0vu)j1!)=4OXHU)w4C*n&)oLYMyo*K% zkpec%_h2W@w9p1t{ote3q3-nk1OH{ EN_o1 z(F*%rDz?go^Cgop^ThHNTjlP8vn$eCgI7ab-j7jACf#VRdI(JurEN^rL;8R38ahrP zOc}jX1bzj9TQ=uTJt0-mr^i>~0lp%EC D9Ea05uQrZhW&;hG7KztICZHHG3`^eKluFY1Zf%1oq^lUWt0kQtjL07a=x=