Frontend fixes

This commit is contained in:
DomySh
2022-07-07 23:34:39 +02:00
parent 48037adc1d
commit 6e317defbf
14 changed files with 40 additions and 117 deletions

View File

@@ -1,9 +1,8 @@
from typing import List, Set from typing import List, Set
from netfilterqueue import NetfilterQueue from netfilterqueue import NetfilterQueue
from threading import Lock, Thread
from scapy.all import IP, TCP, UDP from scapy.all import IP, TCP, UDP
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
import os, pcre2, traceback, asyncio import os, pcre2, traceback
from kthread import KThread from kthread import KThread
QUEUE_BASE_NUM = 1000 QUEUE_BASE_NUM = 1000
@@ -51,11 +50,13 @@ class ProtoTypes:
class IPTables: class IPTables:
@staticmethod
def command(params): def command(params):
if os.geteuid() != 0: if os.geteuid() != 0:
exit("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.") exit("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.")
return Popen(["iptables"]+params, stdout=PIPE, stderr=PIPE).communicate() return Popen(["iptables"]+params, stdout=PIPE, stderr=PIPE).communicate()
@staticmethod
def list_filters(param): def list_filters(param):
stdout, strerr = IPTables.command(["-L", str(param), "--line-number", "-n"]) stdout, strerr = IPTables.command(["-L", str(param), "--line-number", "-n"])
output = [ele.split() for ele in stdout.decode().split("\n")] output = [ele.split() for ele in stdout.decode().split("\n")]
@@ -69,21 +70,27 @@ class IPTables:
"details": " ".join(ele[6:]) if len(ele) >= 7 else "", "details": " ".join(ele[6:]) if len(ele) >= 7 else "",
} for ele in output if len(ele) >= 6 and ele[0].isnumeric()] } for ele in output if len(ele) >= 6 and ele[0].isnumeric()]
@staticmethod
def delete_command(param, id): def delete_command(param, id):
IPTables.command(["-R", str(param), str(id)]) IPTables.command(["-R", str(param), str(id)])
@staticmethod
def create_chain(name): def create_chain(name):
IPTables.command(["-N", str(name)]) IPTables.command(["-N", str(name)])
@staticmethod
def flush_chain(name): def flush_chain(name):
IPTables.command(["-F", str(name)]) IPTables.command(["-F", str(name)])
@staticmethod
def add_chain_to_input(name): def add_chain_to_input(name):
IPTables.command(["-I", "INPUT", "-j", str(name)]) IPTables.command(["-I", "INPUT", "-j", str(name)])
@staticmethod
def add_chain_to_output(name): def add_chain_to_output(name):
IPTables.command(["-I", "OUTPUT", "-j", str(name)]) IPTables.command(["-I", "OUTPUT", "-j", str(name)])
@staticmethod
def add_s_to_c(proto, port, queue_range): def add_s_to_c(proto, port, queue_range):
init, end = queue_range init, end = queue_range
if init > end: init, end = end, init if init > end: init, end = end, init
@@ -94,6 +101,7 @@ class IPTables:
f"{init}" if init == end else f"{init}:{end}", "--queue-bypass" f"{init}" if init == end else f"{init}:{end}", "--queue-bypass"
]) ])
@staticmethod
def add_c_to_s(proto, port, queue_range): def add_c_to_s(proto, port, queue_range):
init, end = queue_range init, end = queue_range
if init > end: init, end = end, init if init > end: init, end = end, init
@@ -159,12 +167,16 @@ class FiregexFilterManager:
)) ))
return res return res
def add(self, proto, port, func_c_to_s, func_s_to_c, n_threads = 1): def add(self, proto, port, func, n_threads = 1):
for ele in self.get(): for ele in self.get():
if int(port) == ele.port: return None if int(port) == ele.port: return None
queues_c_to_s, codes = bind_queues(func_c_to_s, n_threads)
def c_to_s(pkt, data): return func(pkt, data, True)
def s_to_c(pkt, data): return func(pkt, data, False)
queues_c_to_s, codes = bind_queues(c_to_s, n_threads)
IPTables.add_c_to_s(proto, port, codes) IPTables.add_c_to_s(proto, port, codes)
queues_s_to_c, codes = bind_queues(func_s_to_c, n_threads) queues_s_to_c, codes = bind_queues(s_to_c, n_threads)
IPTables.add_s_to_c(proto, port, codes) IPTables.add_s_to_c(proto, port, codes)
return queues_c_to_s + queues_s_to_c return queues_c_to_s + queues_s_to_c
@@ -210,11 +222,11 @@ class Proxy:
def start(self): def start(self):
self.manager.delete_by_port(self.port) self.manager.delete_by_port(self.port)
def c_to_s(pkt, data): def regex_filter(pkt, data, by_client):
packet = bytes(data[TCP].payload) packet = bytes(data[TCP if TCP in data else UDP].payload)
try: try:
for filter in self.filters: for filter in self.filters:
if filter.c_to_s: if (by_client and filter.c_to_s) or (not by_client and filter.s_to_c):
match = filter.check(packet) match = filter.check(packet)
if (filter.is_blacklist and match) or (not filter.is_blacklist and not match): if (filter.is_blacklist and match) or (not filter.is_blacklist and not match):
filter.blocked+=1 filter.blocked+=1
@@ -225,22 +237,7 @@ class Proxy:
pass pass
pkt.accept() pkt.accept()
def s_to_c(pkt, data): self.queue_list = self.manager.add(ProtoTypes.TCP, self.port, regex_filter)
packet = bytes(data[TCP].payload)
try:
for filter in self.filters:
if filter.s_to_c:
match = filter.check(packet)
if (filter.is_blacklist and match) or (not filter.is_blacklist and not match):
filter.blocked+=1
self.callback_blocked_update(filter)
pkt.drop()
return
except IndexError:
pass
pkt.accept()
self.queue_list = self.manager.add(ProtoTypes.TCP, self.port, c_to_s, s_to_c)
for ele in self.queue_list: for ele in self.queue_list:
self.threads.append(KThread(target=ele.run)) self.threads.append(KThread(target=ele.run))
self.threads[-1].daemon = True self.threads[-1].daemon = True

View File

@@ -1,7 +1,6 @@
import secrets
import threading import threading
from proxy import Filter, Proxy from proxy import Filter, Proxy
import random, string, os, sqlite3, socket, asyncio import os, sqlite3, socket, asyncio
from base64 import b64decode from base64 import b64decode
LOCALHOST_IP = socket.gethostbyname(os.getenv("LOCALHOST_IP","127.0.0.1")) LOCALHOST_IP = socket.gethostbyname(os.getenv("LOCALHOST_IP","127.0.0.1"))

12
frontend/build/asset-manifest.json Executable file → Normal file
View File

@@ -1,13 +1,13 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.c375ae17.css", "main.css": "/static/css/main.0efd334b.css",
"main.js": "/static/js/main.b694f5e6.js", "main.js": "/static/js/main.0d2ca4e6.js",
"index.html": "/index.html", "index.html": "/index.html",
"main.c375ae17.css.map": "/static/css/main.c375ae17.css.map", "main.0efd334b.css.map": "/static/css/main.0efd334b.css.map",
"main.b694f5e6.js.map": "/static/js/main.b694f5e6.js.map" "main.0d2ca4e6.js.map": "/static/js/main.0d2ca4e6.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.c375ae17.css", "static/css/main.0efd334b.css",
"static/js/main.b694f5e6.js" "static/js/main.0d2ca4e6.js"
] ]
} }

2
frontend/build/index.html Executable file → Normal file
View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.b694f5e6.js"></script><link href="/static/css/main.c375ae17.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.0d2ca4e6.js"></script><link href="/static/css/main.0efd334b.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

View File

@@ -0,0 +1,2 @@
@import url(https://fonts.googleapis.com/css2?family=Lato&display=swap);.center-flex,.center-flex-row{align-items:center;display:flex;justify-content:center}.center-flex-row{flex-direction:column}.flex-spacer{flex-grow:1}.Footer_center-flex-row__EeEEN,.Footer_center-flex__vCncJ,.Footer_footer__PxxIj{align-items:center;display:flex;justify-content:center}.Footer_center-flex-row__EeEEN{flex-direction:column}.Footer_flex-spacer__MHTsy{flex-grow:1}.Footer_footer__PxxIj{background-color:#242a33;height:150px;margin-top:50px}.Header_header__OKWO7{align-items:center;background-color:#242a33;display:flex;height:140px;justify-content:center;width:100%}.Header_logo__shVBB{height:70%;margin-left:40px;width:200px}body{font-family:Lato,sans-serif;margin:0}.ServiceRow_center-flex-row__g7ljt,.ServiceRow_center-flex__BYani,.ServiceRow_row__X48wF{align-items:center;display:flex;justify-content:center}.ServiceRow_center-flex-row__g7ljt{flex-direction:column}.ServiceRow_flex-spacer__zolmX{flex-grow:1}::-webkit-scrollbar{background:#333;cursor:pointer;margin:3px;width:12px}::-webkit-scrollbar-thumb{background:#757575;border-radius:8px}.ServiceRow_row__X48wF{border-radius:20px;margin:10px;padding:30px 0;width:95%}.ServiceRow_name__fL\+Lz{color:#fff;font-size:2.3em;font-weight:bolder;margin-bottom:13px;margin-right:10px}.RegexView_box__PVbdO{margin:5px;padding:30px}.RegexView_regex_text__rxij9{background-color:#25262b;border-radius:15px;padding:10px}
/*# sourceMappingURL=main.0efd334b.css.map*/

View File

@@ -1 +1 @@
{"version":3,"file":"static/css/main.c375ae17.css","mappings":"wEAUA,8BAGE,mBAFA,aACA,sBACA,CAGF,iBAEE,sBAGF,aACE,YAZF,gFAGE,mBAFA,aACA,sBACA,CAGF,+BAEE,sBAGF,2BACE,YCnBF,sBAGI,yBAFA,aACA,eCJY,CCEhB,sBAKI,mBAFA,wBDLY,CCMZ,aAFA,aAIA,uBALA,UAKA,CAGJ,oBAGI,WADA,iBADA,WAEA,CHVJ,KAEE,4BADA,QACA,CAGF,yFAGE,mBAFA,aACA,sBACA,CAGF,mCAEE,sBAGF,+BACE,YAGF,oBAGE,gBACA,eAFA,UAAU,CADV,UAGA,CAEF,0BACE,mBACA,kBI9BF,uBAGI,mBACA,YAFA,eADA,SAGA,CAIJ,wBAKI,WAJA,gBACA,mBAEA,mBADA,iBAEA,CCbJ,sBAEI,UAAS,CADT,YACU,CAGd,6BAEI,wBHPS,CGQT,mBAFA,YAEA","sources":["index.scss","components/Footer/Footer.module.scss","_vars.scss","components/Header/Header.module.scss","components/ServiceRow/ServiceRow.module.scss","components/RegexView/RegexView.module.scss"],"sourcesContent":["\n@use \"vars\" as *;\n\n@import url('https://fonts.googleapis.com/css2?family=Lato&display=swap');\n\nbody {\n margin: 0;\n font-family: 'Lato', sans-serif;\n}\n\n.center-flex{\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.center-flex-row{\n @extend .center-flex;\n flex-direction: column;\n}\n\n.flex-spacer{\n flex-grow: 1;\n}\n\n::-webkit-scrollbar {\n width: 12px;\n margin:3px;\n background: #333;\n cursor: pointer;\n}\n::-webkit-scrollbar-thumb {\n background: #757575;\n border-radius: 8px;\n}","@use \"../../vars\" as *;\r\n@use \"../../index.scss\" as *;\r\n\r\n.footer{\r\n height: 150px;\r\n margin-top: 50px;\r\n background-color: $primary_color;\r\n @extend .center-flex;\r\n}","\r\n$primary_color: #242a33;\r\n$second_color: #1A1B1E;\r\n$third_color:#25262b;\r\n","\r\n@use \"../../vars\" as *;\r\n\r\n.header{\r\n width: 100%;\r\n height: 140px;\r\n background-color: $primary_color;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.logo{\r\n width: 200px;\r\n margin-left: 40px;\r\n height: 70%;\r\n}","\r\n@use \"../../index.scss\" as *;\r\n\r\n.row{\r\n width: 95%;\r\n padding: 30px 0px;\r\n border-radius: 20px;\r\n margin: 10px;\r\n @extend .center-flex;\r\n}\r\n\r\n.name{\r\n font-size: 2.3em;\r\n font-weight: bolder;\r\n margin-right: 10px;\r\n margin-bottom: 13px;\r\n color:#FFF;\r\n}","\r\n@use \"../../vars\" as *;\r\n\r\n.box{\r\n padding:30px;\r\n margin:5px;\r\n}\r\n\r\n.regex_text{\r\n padding: 10px;\r\n background-color: $third_color;\r\n border-radius: 15px;\r\n}"],"names":[],"sourceRoot":""} {"version":3,"file":"static/css/main.0efd334b.css","mappings":"wEAUA,8BAGE,mBAFA,aACA,sBACA,CAGF,iBAEE,sBAGF,aACE,YAZF,gFAGE,mBAFA,aACA,sBACA,CAGF,+BAEE,sBAGF,2BACE,YCnBF,sBAGI,yBAFA,aACA,eCJY,CCEhB,sBAKI,mBAFA,wBDLY,CCMZ,aAFA,aAIA,uBALA,UAKA,CAGJ,oBAGI,WADA,iBADA,WAEA,CHVJ,KAEE,4BADA,QACA,CAGF,yFAGE,mBAFA,aACA,sBACA,CAGF,mCAEE,sBAGF,+BACE,YAGF,oBAGE,gBACA,eAFA,UAAU,CADV,UAGA,CAEF,0BACE,mBACA,kBI9BF,uBAGI,mBACA,YAFA,eADA,SAGA,CAIJ,yBAKI,WAJA,gBACA,mBAEA,mBADA,iBAEA,CCbJ,sBAEI,UAAS,CADT,YACU,CAGd,6BAEI,wBHPS,CGQT,mBAFA,YAEA","sources":["index.scss","components/Footer/Footer.module.scss","_vars.scss","components/Header/Header.module.scss","components/ServiceRow/ServiceRow.module.scss","components/RegexView/RegexView.module.scss"],"sourcesContent":["\n@use \"vars\" as *;\n\n@import url('https://fonts.googleapis.com/css2?family=Lato&display=swap');\n\nbody {\n margin: 0;\n font-family: 'Lato', sans-serif;\n}\n\n.center-flex{\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.center-flex-row{\n @extend .center-flex;\n flex-direction: column;\n}\n\n.flex-spacer{\n flex-grow: 1;\n}\n\n::-webkit-scrollbar {\n width: 12px;\n margin:3px;\n background: #333;\n cursor: pointer;\n}\n::-webkit-scrollbar-thumb {\n background: #757575;\n border-radius: 8px;\n}","@use \"../../vars\" as *;\r\n@use \"../../index.scss\" as *;\r\n\r\n.footer{\r\n height: 150px;\r\n margin-top: 50px;\r\n background-color: $primary_color;\r\n @extend .center-flex;\r\n}","\r\n$primary_color: #242a33;\r\n$second_color: #1A1B1E;\r\n$third_color:#25262b;\r\n","\r\n@use \"../../vars\" as *;\r\n\r\n.header{\r\n width: 100%;\r\n height: 140px;\r\n background-color: $primary_color;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.logo{\r\n width: 200px;\r\n margin-left: 40px;\r\n height: 70%;\r\n}","\r\n@use \"../../index.scss\" as *;\r\n\r\n.row{\r\n width: 95%;\r\n padding: 30px 0px;\r\n border-radius: 20px;\r\n margin: 10px;\r\n @extend .center-flex;\r\n}\r\n\r\n.name{\r\n font-size: 2.3em;\r\n font-weight: bolder;\r\n margin-right: 10px;\r\n margin-bottom: 13px;\r\n color:#FFF;\r\n}","\r\n@use \"../../vars\" as *;\r\n\r\n.box{\r\n padding:30px;\r\n margin:5px;\r\n}\r\n\r\n.regex_text{\r\n padding: 10px;\r\n background-color: $third_color;\r\n border-radius: 15px;\r\n}"],"names":[],"sourceRoot":""}

View File

@@ -1,2 +0,0 @@
@import url(https://fonts.googleapis.com/css2?family=Lato&display=swap);.center-flex,.center-flex-row{align-items:center;display:flex;justify-content:center}.center-flex-row{flex-direction:column}.flex-spacer{flex-grow:1}.Footer_center-flex-row__yo4XA,.Footer_center-flex__uvxL9,.Footer_footer__S9pCA{align-items:center;display:flex;justify-content:center}.Footer_center-flex-row__yo4XA{flex-direction:column}.Footer_flex-spacer__VEUAB{flex-grow:1}.Footer_footer__S9pCA{background-color:#242a33;height:150px;margin-top:50px}.Header_header__Ri4em{align-items:center;background-color:#242a33;display:flex;height:140px;justify-content:center;width:100%}.Header_logo__3Bvhn{height:70%;margin-left:40px;width:200px}body{font-family:Lato,sans-serif;margin:0}.ServiceRow_center-flex-row__E5vBK,.ServiceRow_center-flex__hmJif,.ServiceRow_row__-A-i2{align-items:center;display:flex;justify-content:center}.ServiceRow_center-flex-row__E5vBK{flex-direction:column}.ServiceRow_flex-spacer__vmC0u{flex-grow:1}::-webkit-scrollbar{background:#333;cursor:pointer;margin:3px;width:12px}::-webkit-scrollbar-thumb{background:#757575;border-radius:8px}.ServiceRow_row__-A-i2{border-radius:20px;margin:10px;padding:30px 0;width:95%}.ServiceRow_name__6f1O6{color:#fff;font-size:2.3em;font-weight:bolder;margin-bottom:13px;margin-right:10px}.RegexView_box__g-S5R{margin:5px;padding:30px}.RegexView_regex_text__Fy5MY{background-color:#25262b;border-radius:15px;padding:10px}
/*# sourceMappingURL=main.c375ae17.css.map*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,70 +0,0 @@
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* React Router v6.3.0
*
* Copyright (c) Remix Software Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

View File

@@ -70,11 +70,13 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
<MediaQuery smallerThan="md" styles={{ display: 'none' }}><div> <MediaQuery smallerThan="md" styles={{ display: 'none' }}><div>
<div className="center-flex-row"> <div className="center-flex-row">
<div className="center-flex"><Title className={style.name}>{service.name}</Title> <Badge size="xl" gradient={{ from: 'indigo', to: 'cyan' }} variant="gradient">:{service.port}</Badge></div> <div className="center-flex"><Title className={style.name}>{service.name}</Title> <Badge size="xl" gradient={{ from: 'indigo', to: 'cyan' }} variant="gradient">:{service.port}</Badge></div>
<Badge color={status_color} radius="sm" size="lg" variant="filled">Status: <u>{service.status}</u></Badge>
</div> </div>
</div></MediaQuery> </div></MediaQuery>
<MediaQuery largerThan="md" styles={{ display: 'none' }}><div> <MediaQuery largerThan="md" styles={{ display: 'none' }}><div>
<div className="center-flex"> <div className="center-flex">
<div className="center-flex"><Title className={style.name}>{service.name}</Title> <Badge size="xl" gradient={{ from: 'indigo', to: 'cyan' }} variant="gradient">:{service.port}</Badge></div> <div className="center-flex"><Title className={style.name}>{service.name}</Title> <Badge size="xl" gradient={{ from: 'indigo', to: 'cyan' }} variant="gradient">:{service.port}</Badge></div>
<Badge style={{marginLeft:"20px"}} color={status_color} radius="sm" size="lg" variant="filled">Status: <u>{service.status}</u></Badge>
<Space w="xl" /> <Space w="xl" />
</div> </div>
</div></MediaQuery> </div></MediaQuery>
@@ -93,9 +95,8 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
</MediaQuery> </MediaQuery>
<div className="center-flex-row"> <div className="center-flex-row">
<Badge style={{marginBottom:"20px"}} color={status_color} radius="sm" size="xl" variant="filled">Status: <u>{service.status}</u></Badge> <Badge style={{marginBottom:"8px"}} color="yellow" radius="sm" size="md" variant="filled">Connections Blocked: {service.n_packets}</Badge>
<Badge style={{marginBottom:"8px"}}color="violet" radius="sm" size="lg" variant="filled">Regex: {service.n_regex}</Badge> <Badge color="violet" radius="sm" size="md" variant="filled">Regex: {service.n_regex}</Badge>
<Badge color="yellow" radius="sm" size="lg" variant="filled">Connections Blocked: {service.n_packets}</Badge>
</div> </div>
<MediaQuery largerThan="md" styles={{ display: 'none' }}> <MediaQuery largerThan="md" styles={{ display: 'none' }}>
<div className='flex-spacer' /> <div className='flex-spacer' />