Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,282 +1,8 @@
|
|
| 1 |
-
|
| 2 |
-
from
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
return Div(
|
| 10 |
-
H3(title, cls=f"text-black heading-3"),
|
| 11 |
-
P(content, cls=f"l-body mt-6 lg:mt-6"),
|
| 12 |
-
cls="w-full p-6 bg-soft-yellow rounded-2xl xl:p-12 lg:h-[22rem] lg:w-[26rem]")
|
| 13 |
-
|
| 14 |
-
def faq_item(question, answer, id):
|
| 15 |
-
return accordion(
|
| 16 |
-
id=id, question=question, answer=answer,
|
| 17 |
-
question_cls="text-black s-body",
|
| 18 |
-
answer_cls="s-body text-black/80 col-span-full",
|
| 19 |
-
container_cls=f"{col} justify-between bg-soft-blue rounded-[1.25rem] {bnset}"
|
| 20 |
-
)
|
| 21 |
-
|
| 22 |
-
def hero_section():
|
| 23 |
-
return (
|
| 24 |
-
Header(
|
| 25 |
-
Nav(
|
| 26 |
-
A(
|
| 27 |
-
Img(src='/assets/logo.svg', alt='FastHTML', width='105', height='24'),
|
| 28 |
-
href='#'),
|
| 29 |
-
A('Read docs', href='/docs', **_blank,
|
| 30 |
-
cls=f'bg-black text-white py-2 px-4 s-body rounded-[62.5rem] hover:bg-black/80 transition-colors duration-300 px-4 py-1 h-10 {center} justify-center'),
|
| 31 |
-
cls=f'py-2 px-4 {between} items-center rounded-full w-full max-w-[400px] bg-white/50 backdrop-blur-lg border border-white/20'),
|
| 32 |
-
cls=f'fixed top-0 w-full left-0 p-4 {center} justify-center z-50'),
|
| 33 |
-
Section(
|
| 34 |
-
Div(
|
| 35 |
-
File('assets/hero-shapes.svg'),
|
| 36 |
-
cls='absolute z-0 lg:-top-[15%] top-0 left-1/2 -translate-x-1/2 grid grid-cols-1 grid-rows-1 w-[120%] aspect-square max-w-[2048px] min-w-[900px]'),
|
| 37 |
-
Div(
|
| 38 |
-
Div(cls='lg:flex-1 max-lg:basis-[152px]'),
|
| 39 |
-
Div(
|
| 40 |
-
H1(description, cls='heading-1 max-w-3xl'),
|
| 41 |
-
P('Built on solid web foundations, not the latest fads - with\nFastHTML you can get started on anything from simple dashboards to\nscalable web applications in minutes.',
|
| 42 |
-
cls='m-body max-w-[40rem] text-center'),
|
| 43 |
-
cls=f'flex-1 {col} items-center justify-center gap-6 text-center w-full text-black'
|
| 44 |
-
),
|
| 45 |
-
Div(
|
| 46 |
-
A('Learn more', href='https://fastht.ml/about', **_blank,
|
| 47 |
-
cls=f'{bnset} m-body px-4 py-1 rounded-full bg-black hover:bg-black/80 transition-colors duration-300 text-white h-[76px] w-full max-w-[350px] flex items-center justify-center'),
|
| 48 |
-
video_button('Watch intro', '/assets/thumb.png', '7min 30sec', "QqZUzkPcU7A?si=lTtHuMT5HPC66-49"),
|
| 49 |
-
cls=f'flex-1 {center} justify-center content-center flex-wrap lg:gap-6 gap-4 m-body'),
|
| 50 |
-
video_player('Try now'),
|
| 51 |
-
cls=f'{col} flex-1 relative px-4 lg:px-16'),
|
| 52 |
-
cls=f'{col} relative w-full h-screen max-h-[1024px] min-h-[720px] overflow-hidden bg-grey')
|
| 53 |
-
)
|
| 54 |
-
|
| 55 |
-
def code_display(file_name, code_snippet, snippet_id):
|
| 56 |
-
return Div(
|
| 57 |
-
Div(
|
| 58 |
-
Div(
|
| 59 |
-
P(file_name, cls=f"xs-mono-body {center}"),
|
| 60 |
-
Button(
|
| 61 |
-
Div(
|
| 62 |
-
Img(cls="button-content w-4 h-4", src="assets/icons/copy-icon.svg", alt="Copy"),
|
| 63 |
-
Span("Copied!", cls=f"absolute bg-inherit rounded-l-[0.5rem] {center} py-2 h-full right-0 copied-text overflow-hidden w-0 peer-clicked:w-fit s-body text-white/80 transition-transform transition-all duration-600 ease-out"),
|
| 64 |
-
cls=f"relative bg-black/20 rounded-[0.5rem] {center} p-2 h-8 w-fit"),
|
| 65 |
-
cls="copy-button"),
|
| 66 |
-
cls=f"w-full {between}"),
|
| 67 |
-
cls="bg-black/20 text-white/80 w-full max-w-2xl lg:max-w-xl p-4 rounded-2xl"),
|
| 68 |
-
Pre(
|
| 69 |
-
Code(code_snippet, cls="python w-full mono-body"),
|
| 70 |
-
id=snippet_id,
|
| 71 |
-
cls="code-snippet relative max-h-[25rem] overflow-hidden hide-scrollbar"),
|
| 72 |
-
Div(cls="absolute code-fade-out bottom-0 left-0 right-0 h-16 bg-gradient-to-b from-transparent to-[#3a2234] pointer-events-none"),
|
| 73 |
-
cls=f"relative {col} gap-6 lg:max-w-[45rem] w-full overflow-hidden"
|
| 74 |
-
)
|
| 75 |
-
|
| 76 |
-
def code_demo(title, file_name, code_snippet, demo_content, is_active=False):
|
| 77 |
-
snippet_id = f"{title.lower().replace(' ', '-')}-code-snippet"
|
| 78 |
-
demo_cls = f"{center} my-11 p-4 flex-none whitespace-normal justify-center h-96 rounded-3xl bg-soft-purple lg:p-8 w-full max-w-2xl lg:max-w-md lg:mx-28 lg:my-8 overflow-y-auto {'lg:items-start hide-scrollbar' if snippet_id == 'reusable-code-snippet' else ''}"
|
| 79 |
-
return Div(
|
| 80 |
-
code_display(file_name, code_snippet, snippet_id),
|
| 81 |
-
Div(demo_content, cls=demo_cls),
|
| 82 |
-
aria_labelledby=f"tab-{title.lower().replace(' ', '-')}", role="tabpanel",
|
| 83 |
-
cls=f"code-container pt-8 lg:pt-16 tab-panel relative hide-scrollbar toggle-element {col} lg:flex-row lg:justify-between overflow-hidden w-full lg:max-w-[1440px] xl:mx-auto {'hidden' if not is_active else ''}",
|
| 84 |
-
id=f"{title.lower().replace(' ', '-')}-code-demo")
|
| 85 |
-
|
| 86 |
-
def tab_button(title, is_active=False):
|
| 87 |
-
classes = f"z-10 button-container flex-none relative px-8 py-2 w-[10.59375rem] h-11 rounded-full {center}"
|
| 88 |
-
active = f"{classes} current active transition-all duration-300 text-white"
|
| 89 |
-
inactive = f"{classes} text-white/80 hover:text-white"
|
| 90 |
-
return Li(
|
| 91 |
-
Button(
|
| 92 |
-
Div(title, cls="m-body w-max mx-auto"),
|
| 93 |
-
id=f"tab-{title.lower().replace(' ', '-')}",
|
| 94 |
-
cls="toggle-button w-full cursor-pointer",
|
| 95 |
-
data_target=f"{title.lower().replace(' ', '-')}-code-demo",
|
| 96 |
-
tabindex="-1" if not is_active else None,
|
| 97 |
-
name=f"tab-{title.lower().replace(' ', '-')}"),
|
| 98 |
-
role="tab", aria_selected="true" if is_active else "false",
|
| 99 |
-
cls=active if is_active else inactive)
|
| 100 |
-
|
| 101 |
-
async def component_preview_section():
|
| 102 |
-
cs = await components()
|
| 103 |
-
return Section(
|
| 104 |
-
Div(
|
| 105 |
-
Div(
|
| 106 |
-
H2("This home page is a FastHTML app.", cls="text-white heading-2 pt-8"),
|
| 107 |
-
P("Click the buttons below to see four small, live components in action.", cls=f"text-white pt-8 l-body {maxrem(32)}"),
|
| 108 |
-
cls=f"{maxrem(50)} mx-auto {col} {center} text-center gap-6"
|
| 109 |
-
),
|
| 110 |
-
*[code_demo(title, file_name, code_snippet, demo_content, i == 0) for i, (title, file_name, code_snippet, demo_content) in enumerate(cs)],
|
| 111 |
-
Ul(
|
| 112 |
-
*[tab_button(title, i == 0) for i, (title, _, _, _) in enumerate(cs)],
|
| 113 |
-
Div(id="highlighter", cls=f"{inset} z-0 highlighter w-[10.59375rem] absolute bg-white/20 h-[2.75rem] rounded-[62.5rem] transition-transform duration-300"),
|
| 114 |
-
role="tablist", id="tab-list",
|
| 115 |
-
cls=f"relative mt-12 text-white/80 flex-none rounded-[62.5rem] bg-black/20 p-2 max-w-full overflow-x-auto lg:mx-auto {center} hide-scrollbar lg:max-w-[43.375rem]"),
|
| 116 |
-
cls=f"{col} {center}"),
|
| 117 |
-
cls="relative bg-purple px-4 lg:px-16 pb-24 -mt-8 lg:-mt-10 flex-col xl:items-center items-start gap-6 lg:gap-16 rounded-t-3xl lg:rounded-t-[2.5rem] overflow-x-hidden")
|
| 118 |
-
|
| 119 |
-
def stacked_cards_section():
|
| 120 |
-
return Section(
|
| 121 |
-
Div(
|
| 122 |
-
Div(
|
| 123 |
-
Div(
|
| 124 |
-
P("TECH STACK", cls="mono-body text-opacity-60"),
|
| 125 |
-
H2("FastHTML scales up and scales down.", cls="text-black heading-2"),
|
| 126 |
-
P("Read more about our ",
|
| 127 |
-
A("design philosophy here", href="https://fastht.ml/about/vision", **_blank,
|
| 128 |
-
cls="border-b-2 border-b-black/30 hover:border-b-black/80"),
|
| 129 |
-
", or click a button below:",
|
| 130 |
-
cls=f"l-body {maxrem(32)}"),
|
| 131 |
-
cls=f"{maxrem(50)} mx-auto {col} {center} text-center gap-6"),
|
| 132 |
-
cls="py-8 lg:pt-16 px-4 lg:px-16 rounded-t-3xl lg:rounded-t-[2.5rem] bg-green"),
|
| 133 |
-
cls="bg-yellow sticky top-0 bottom-[calc(100%-300px)] w-full"),
|
| 134 |
-
Div(
|
| 135 |
-
Div(
|
| 136 |
-
*[stacked_card(title, description, tech_stack, "bg-soft-green") for title, description, tech_stack in stacked],
|
| 137 |
-
id="stacked-cards", cls=f"{maxrem(50)} mx-auto"),
|
| 138 |
-
cls="px-4 lg:px-16 w-full bg-green pt-8"),
|
| 139 |
-
id="stacked-cards-section", cls="relative")
|
| 140 |
-
|
| 141 |
-
def samples_section():
|
| 142 |
-
text = "FastHTML can be used for everything from collaborative games to multi-modal UI. We've selected small self-contained examples for you to learn from."
|
| 143 |
-
return section_wrapper(
|
| 144 |
-
(section_header("SAMPLES", "See FastHTML in action", text, max_width=40),
|
| 145 |
-
Div(
|
| 146 |
-
*[Div(
|
| 147 |
-
A(
|
| 148 |
-
File(f"assets/{svg}"),
|
| 149 |
-
Div(
|
| 150 |
-
P(name, cls="border-b-2 border-b-black/30 hover:border-b-black/80 regular-body"),
|
| 151 |
-
Img(src=f"{icons}/arrow-up-right.svg", alt="Arrow right icon", cls="group-hover:translate-y-[-0.1rem] transition-all ease-in-out duration-300"),
|
| 152 |
-
cls=f"{gap2} transition-transform transform relative items-center mt-4 lg:mt-6"),
|
| 153 |
-
href=url, cls=f"{col} items-center"),
|
| 154 |
-
cls="group px-2"
|
| 155 |
-
) for name, svg, url in samples],
|
| 156 |
-
cls="grid max-w-5xl lg:grid-cols-4 lg:max-w-7xl lg:gap-x-12 grid-cols-2 gap-x-4 gap-y-8 w-full mx-auto"),
|
| 157 |
-
A("Discover all", href=eg_url,
|
| 158 |
-
cls=f"{bnset} bg-black text-white py-2 px-4 s-body rounded-full hover:bg-black/70 transition-colors duration-300")),
|
| 159 |
-
bg_color="grey")
|
| 160 |
-
|
| 161 |
-
def how_it_works_section():
|
| 162 |
-
msg = "With FastHTML you create good-looking modern web applications in pure Python and deploy them in minutes."
|
| 163 |
-
return section_wrapper(
|
| 164 |
-
(Div(
|
| 165 |
-
section_header( "GET STARTED IN MINUTES", "The fastest way to create a real web application.", msg),
|
| 166 |
-
cls="max-w-3xl w-full mx-auto flex-col items-center text-center gap-6 mb-8 lg:mb-8"),
|
| 167 |
-
Div(*[benefit(title, content) for title, content in benefits],
|
| 168 |
-
cls=f"{col} w-full lg:flex-row gap-4 items-center lg:gap-8 max-w-7xl mx-auto justify-center"),),
|
| 169 |
-
bg_color="yellow", flex=False)
|
| 170 |
-
|
| 171 |
-
def faq_section():
|
| 172 |
-
return section_wrapper(
|
| 173 |
-
Div(
|
| 174 |
-
section_header( "FAQ", "Questions? Answers.", "Your top FastHTML questions clarified.",
|
| 175 |
-
max_width=21, center=False),
|
| 176 |
-
Div(
|
| 177 |
-
*[faq_item(question, answer, i+3) for i, (question, answer) in enumerate(faqs)],
|
| 178 |
-
cls=f"{col} gap-4 {maxrem(32)} transition ease-out delay-[300ms]"),
|
| 179 |
-
cls=f"{section_base} w-full mx-auto lg:flex-row items-start max-w-7xl"),
|
| 180 |
-
bg_color="blue")
|
| 181 |
-
|
| 182 |
-
def testimonials_section():
|
| 183 |
-
testimonial_cards = [testimonial_card(i, *args) for i, args in enumerate(testimonials)]
|
| 184 |
-
return section_wrapper(
|
| 185 |
-
Div(
|
| 186 |
-
section_header(
|
| 187 |
-
"LOVE IS IN THE AIR", "What the experts say",
|
| 188 |
-
"Top web programmers tell us that they love working with FastHTML.",
|
| 189 |
-
max_width=21, center=False),
|
| 190 |
-
carousel(testimonial_cards),
|
| 191 |
-
cls=f"{section_base} {maxrem(90)} mx-auto lg:flex-row items-start"),
|
| 192 |
-
bg_color="pink")
|
| 193 |
-
|
| 194 |
-
def footer_link(text, href, **kw):
|
| 195 |
-
return Li(A(
|
| 196 |
-
Span(text, cls="border-b border-b-transparent border-b-white/50"),
|
| 197 |
-
Img(src=f"{icons}/arrow-up-right-white.svg", alt="Arrow right icon", width="16", height="16", cls="w-4 h-4"),
|
| 198 |
-
href=href, cls=f"{gap2} items-center hover:text-white border-b border-b-transparent hover:border-b-white", **kw))
|
| 199 |
-
|
| 200 |
-
def footer():
|
| 201 |
-
return Section(
|
| 202 |
-
Div(
|
| 203 |
-
Div(
|
| 204 |
-
P("© 2024 onwards AnswerDotAI. All rights reserved.", cls="mr-auto"),
|
| 205 |
-
Nav(
|
| 206 |
-
Ul(
|
| 207 |
-
footer_link("Github", "https://github.com/AnswerDotAI/fasthtml", **_blank),
|
| 208 |
-
footer_link("Join Discord", "https://discord.gg/qcXvcxMhdP", **_blank),
|
| 209 |
-
footer_link("Docs", "/docs", **_blank),
|
| 210 |
-
footer_link("Site design", "https://tinloof.com/", **_blank),
|
| 211 |
-
cls="flex max-lg:flex-col max-lg:items-start gap-4 lg:gap-6 flex-wrap")),
|
| 212 |
-
cls="relative z-[1] mono-s flex max-lg:flex-col gap-6 text-white/80 px-4 lg:px-16 pb-16"),
|
| 213 |
-
Div(
|
| 214 |
-
Div(
|
| 215 |
-
File("assets/footer-shapes.svg"),
|
| 216 |
-
cls=f"absolute z-0 lg:-top-[15%] top-0 left-1/2 -translate-x-1/2 grid grid-cols-1 grid-rows-1 lg:w-[150%] w-[200%] aspect-square max-w-none min-w-max"),
|
| 217 |
-
File("assets/footer-path.svg"),
|
| 218 |
-
cls=f"relative z-0 w-full px-4 lg:px-16 pb-1 {col} flex-1 justify-end"),
|
| 219 |
-
cls=f"relative w-full h-[420px] lg:h-[600px] {col} pt-8 lg:pt-12 rounded-t-3xl lg:rounded-t-[2.5rem] bg-black overflow-hidden -mt-8 lg:-mt-10"))
|
| 220 |
-
|
| 221 |
-
hdrs = [
|
| 222 |
-
Meta(charset='UTF-8'),
|
| 223 |
-
Meta(name='viewport', content='width=device-width, initial-scale=1.0, maximum-scale=1.0'),
|
| 224 |
-
Meta(name='description', content=description),
|
| 225 |
-
*Favicon('favicon.ico', 'favicon-dark.ico'),
|
| 226 |
-
*Socials(title='FastHTML',
|
| 227 |
-
description=description,
|
| 228 |
-
site_name='fastht.ml',
|
| 229 |
-
twitter_site='@answerdotai',
|
| 230 |
-
image=f'/assets/og-sq.png',
|
| 231 |
-
url=''),
|
| 232 |
-
# surrsrc,
|
| 233 |
-
Script(src='https://cdn.jsdelivr.net/gh/gnat/surreal@main/surreal.js'),
|
| 234 |
-
scopesrc,
|
| 235 |
-
Link(href='css/main.css', rel='stylesheet'),
|
| 236 |
-
Link(href='css/tailwind.css', rel='stylesheet'),
|
| 237 |
-
Link(href='css/stack.css', rel='stylesheet'),
|
| 238 |
-
Link(href='css/preview-stack.css', rel='stylesheet'),
|
| 239 |
-
Link(href='css/highlighter-theme.css', rel='stylesheet')]
|
| 240 |
-
|
| 241 |
-
from about.main import app as about_app
|
| 242 |
-
routes = [Mount(f"/about", about_app),
|
| 243 |
-
Mount('/docs', StaticFiles(directory='docs', html=True)),
|
| 244 |
-
]
|
| 245 |
-
|
| 246 |
-
bodykw = {"class": "relative bg-black font-geist text-black/80 font-details-off"}
|
| 247 |
-
app,rt = fast_app(hdrs=hdrs, default_hdrs=False, bodykw=bodykw, on_startup=[startup], routes=routes)
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
scripts = (
|
| 251 |
-
Script(src='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js'),
|
| 252 |
-
Script(src='https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js'),
|
| 253 |
-
# Script(src='js/videoPopup.js'),
|
| 254 |
-
Script(src='js/pythonHighlighter.js'),
|
| 255 |
-
Script(src='js/carouselScroll.js'),
|
| 256 |
-
Script(src='js/stack.js'),
|
| 257 |
-
Script(src='js/togglePreview.js'),
|
| 258 |
-
Script(src='js/codeOverflow.js'),
|
| 259 |
-
Script(src='js/copyCode.js'),
|
| 260 |
-
)
|
| 261 |
-
|
| 262 |
-
from fastcore.xtras import timed_cache
|
| 263 |
-
|
| 264 |
-
@timed_cache(seconds=60)
|
| 265 |
-
async def home():
|
| 266 |
-
return (Title(f"FastHTML - {description}"),
|
| 267 |
-
Main(
|
| 268 |
-
hero_section(),
|
| 269 |
-
await component_preview_section(),
|
| 270 |
-
how_it_works_section(),
|
| 271 |
-
stacked_cards_section(),
|
| 272 |
-
samples_section(),
|
| 273 |
-
faq_section(),
|
| 274 |
-
testimonials_section(),
|
| 275 |
-
footer()),
|
| 276 |
-
*scripts)
|
| 277 |
-
|
| 278 |
-
@rt("/")
|
| 279 |
-
async def get(): return await home()
|
| 280 |
-
|
| 281 |
-
serve()
|
| 282 |
-
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
from src.some_module import your_pipeline # whatever you need
|
| 3 |
+
|
| 4 |
+
st.title("Home-FastHTML in Streamlit")
|
| 5 |
+
input_html = st.text_area("Paste HTML here")
|
| 6 |
+
if st.button("Transform"):
|
| 7 |
+
output = your_pipeline(input_html)
|
| 8 |
+
st.code(output, language="html")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|