Spaces:
Running
Running
unknown Claude Opus 5.5 commited on
Commit ·
dbed3bc
1
Parent(s): 2ba5d52
Site led by the Turnitin report: first tab and default page, Turnitin-first headline, report -> Smart Humanize -> check again, title and search description, Pricing and About, trademark note
Browse files- app.py +68 -23
- site_pages.py +2 -0
- wallet.py +4 -3
app.py
CHANGED
|
@@ -88,6 +88,11 @@ def _locked(what):
|
|
| 88 |
'<div class="cs-lock-t">Sign in to see your dashboard</div>'
|
| 89 |
'<div class="cs-lock-s">Your runs, scores, downloads and plan are kept in your free account. '
|
| 90 |
'Pasting text works without signing in.</div></div>')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
return (f'<div class="cs-lock"><div class="cs-lock-ico">{UI.LOCK_ICON}🔒</div>'
|
| 92 |
f'<div class="cs-lock-t">Sign in to upload {what}</div>'
|
| 93 |
f'<div class="cs-lock-s">A free account takes a minute, and your first document is free. '
|
|
@@ -1524,15 +1529,30 @@ HEADER = f"""
|
|
| 1524 |
BRAND_HTML = (f'<div class="cs-brand">{_logo}<div><div class="t">{_title}</div>'
|
| 1525 |
'<div class="s">AI detection and humanizing for academic writing</div></div></div>')
|
| 1526 |
|
|
|
|
|
|
|
|
|
|
| 1527 |
FOOTER = f"""
|
| 1528 |
<div class="cs-footer"><div class="bar"></div>
|
| 1529 |
© CS Software Solutions · Tri-Crest Press | <a href="{SITE_URL}" target="_blank">cssoftwaresolutions.in</a><br>
|
| 1530 |
{SP.footer_contact_html()}<br>
|
| 1531 |
-
Rewritten output should be checked for accuracy and properly cited before submission.
|
|
|
|
|
|
|
| 1532 |
</div>"""
|
| 1533 |
|
| 1534 |
# Unscoped CSS (Gradio prefixes the css= string, so the outer containers are pinned here)
|
| 1535 |
-
HEAD = """
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1536 |
""" + SP.CSS + """
|
| 1537 |
#cs-go-pricing, #cs-go-account, #cs-go-formatter, #cs-go-finder, #cs-stop-srv, #cs-go-rephrase-text, #cs-go-rephrase-doc, #cs-go-unlock-smart, #cs-go-unlock-hum, .cs-hidden-nav { display: none !important; }
|
| 1538 |
a.cs-up-go { text-decoration: none !important; display: inline-block; }
|
|
@@ -2072,7 +2092,7 @@ def lock_gate(what):
|
|
| 2072 |
|
| 2073 |
GOTO_ACCOUNT = []
|
| 2074 |
|
| 2075 |
-
with gr.Blocks(title=
|
| 2076 |
head=HEAD) as demo:
|
| 2077 |
user_state = gr.State(None)
|
| 2078 |
TOOLS_UI["user"] = user_state # the formatter / finder log their runs under the signed-in user
|
|
@@ -2102,10 +2122,48 @@ with gr.Blocks(title=f"{APP_NAME} · CS Software Solutions", theme=theme, css=CS
|
|
| 2102 |
sp_force = gr.Button("rephrase", elem_id="cs-go-rephrase-text", elem_classes="cs-hidden-nav", scale=0)
|
| 2103 |
sd_force = gr.Button("rephrase", elem_id="cs-go-rephrase-doc", elem_classes="cs-hidden-nav", scale=0)
|
| 2104 |
|
| 2105 |
-
with gr.Tabs(elem_id="cs-nav", selected="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2106 |
# ============================ SMART HUMANIZE ============================
|
| 2107 |
with gr.Tab("Smart Humanize", id="smart"):
|
| 2108 |
-
gr.HTML('<div class="cs-intro cs-hero"><h2>
|
| 2109 |
'<p>Drop your Word file and the rest is automatic: AI-sounding sentences are found, rewritten and '
|
| 2110 |
'checked again until the score is as low as it can safely go. Numbers, citations, technical '
|
| 2111 |
'terms and your layout stay exactly as they are.</p>'
|
|
@@ -2160,6 +2218,7 @@ with gr.Blocks(title=f"{APP_NAME} · CS Software Solutions", theme=theme, css=CS
|
|
| 2160 |
sd_status = gr.HTML(H.status_idle("Drop your .docx on the left. It starts by itself; nothing to press or set."))
|
| 2161 |
sd_file = gr.File(label="Download humanized .docx", interactive=False)
|
| 2162 |
sd_dl = gr.HTML()
|
|
|
|
| 2163 |
sd_pr_btn = gr.Button("Final check & proofread (keeps the AI score)", variant="secondary")
|
| 2164 |
gr.Markdown("<small>After humanizing: one last full check of the whole document in a "
|
| 2165 |
"single pass: grammar, unclear sentences, academic wording, flow and "
|
|
@@ -2275,24 +2334,6 @@ with gr.Blocks(title=f"{APP_NAME} · CS Software Solutions", theme=theme, css=CS
|
|
| 2275 |
dd_to_smart = gr.Button("Humanize this .docx →")
|
| 2276 |
with gr.Column(scale=2):
|
| 2277 |
dd_html = gr.HTML()
|
| 2278 |
-
with gr.Tab("Turnitin report"):
|
| 2279 |
-
_, tt_open, tt_lockbtn = lock_gate("Turnitin reports")
|
| 2280 |
-
GOTO_ACCOUNT.append(tt_lockbtn)
|
| 2281 |
-
with tt_open:
|
| 2282 |
-
with gr.Column(elem_classes="cs-card"):
|
| 2283 |
-
gr.HTML('<div class="cs-intro"><b>Turnitin report.</b> Your document is checked by '
|
| 2284 |
-
'Turnitin and you get its AI-writing report and similarity report as PDFs '
|
| 2285 |
-
f'(usually in 2–5 minutes). <b>{W.inr(W.usual_price("turnitin", 0))}</b> per '
|
| 2286 |
-
'document, paid from your wallet; nothing is charged if the report cannot be '
|
| 2287 |
-
'produced. Your document is not saved to the Turnitin repository.</div>')
|
| 2288 |
-
tt_in = gr.File(label="Document (.docx, .pdf, .txt)", file_types=[".docx", ".pdf", ".txt"],
|
| 2289 |
-
type="filepath")
|
| 2290 |
-
tt_btn = gr.Button(f"Get Turnitin report — {W.inr(W.usual_price('turnitin', 0))}",
|
| 2291 |
-
variant="primary", size="lg")
|
| 2292 |
-
tt_status = gr.HTML(H.status_idle("Upload your document and press **Get Turnitin "
|
| 2293 |
-
"report**."))
|
| 2294 |
-
tt_files = gr.File(label="Turnitin report (PDF)", file_count="multiple", interactive=False)
|
| 2295 |
-
tt_dl = gr.HTML()
|
| 2296 |
|
| 2297 |
# ============================ HUMANIZER ============================
|
| 2298 |
with gr.Tab("Humanizer", id="humanize", visible=False): # Smart Humanize includes this engine
|
|
@@ -2670,6 +2711,10 @@ with gr.Blocks(title=f"{APP_NAME} · CS Software Solutions", theme=theme, css=CS
|
|
| 2670 |
for b in GOTO_ACCOUNT + [top_signin]:
|
| 2671 |
b.click(lambda: gr.Tabs(selected="account"), None, nav, **HID)
|
| 2672 |
dp_to_smart.click(lambda t: (gr.Tabs(selected="smart"), t), dp_in, [nav, sp_in], **HID)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2673 |
dd_to_smart.click(lambda f: (gr.Tabs(selected="smart"), f if f and str(f).lower().endswith(".docx") else None),
|
| 2674 |
dd_in, [nav, sd_in], **HID)
|
| 2675 |
hp_to_det.click(lambda t: (gr.Tabs(selected="detect"), t), hp_out, [nav, dp_in], **HID)
|
|
|
|
| 88 |
'<div class="cs-lock-t">Sign in to see your dashboard</div>'
|
| 89 |
'<div class="cs-lock-s">Your runs, scores, downloads and plan are kept in your free account. '
|
| 90 |
'Pasting text works without signing in.</div></div>')
|
| 91 |
+
if what == "Turnitin reports": # paid per report: no free document, no paste option
|
| 92 |
+
return (f'<div class="cs-lock"><div class="cs-lock-ico">{UI.LOCK_ICON}🔒</div>'
|
| 93 |
+
'<div class="cs-lock-t">Sign in to get your Turnitin report</div>'
|
| 94 |
+
'<div class="cs-lock-s">A free account takes a minute. Add money to your wallet once, then each '
|
| 95 |
+
'report is paid from it, only when the report is ready.</div></div>')
|
| 96 |
return (f'<div class="cs-lock"><div class="cs-lock-ico">{UI.LOCK_ICON}🔒</div>'
|
| 97 |
f'<div class="cs-lock-t">Sign in to upload {what}</div>'
|
| 98 |
f'<div class="cs-lock-s">A free account takes a minute, and your first document is free. '
|
|
|
|
| 1529 |
BRAND_HTML = (f'<div class="cs-brand">{_logo}<div><div class="t">{_title}</div>'
|
| 1530 |
'<div class="s">AI detection and humanizing for academic writing</div></div></div>')
|
| 1531 |
|
| 1532 |
+
SITE_TITLE = os.getenv("SITE_TITLE", "Real Turnitin AI & Similarity Report ₹550 · Humanizer · CS AI Writing Suite")
|
| 1533 |
+
SITE_DESC = os.getenv("SITE_DESC", "Get your real Turnitin AI-writing and similarity report as PDFs in 2-5 minutes, "
|
| 1534 |
+
"not saved to the Turnitin repository. AI flagged? Lower it with Smart Humanize and check again.")
|
| 1535 |
FOOTER = f"""
|
| 1536 |
<div class="cs-footer"><div class="bar"></div>
|
| 1537 |
© CS Software Solutions · Tri-Crest Press | <a href="{SITE_URL}" target="_blank">cssoftwaresolutions.in</a><br>
|
| 1538 |
{SP.footer_contact_html()}<br>
|
| 1539 |
+
Rewritten output should be checked for accuracy and properly cited before submission.<br>
|
| 1540 |
+
<small>Turnitin is a trademark of Turnitin, LLC. CS AI Writing Suite is an independent service and is not affiliated
|
| 1541 |
+
with or endorsed by Turnitin.</small>
|
| 1542 |
</div>"""
|
| 1543 |
|
| 1544 |
# Unscoped CSS (Gradio prefixes the css= string, so the outer containers are pinned here)
|
| 1545 |
+
HEAD = (f'<meta name="description" content="{html.escape(SITE_DESC, quote=True)}">'
|
| 1546 |
+
f'<meta property="og:title" content="{html.escape(SITE_TITLE, quote=True)}">'
|
| 1547 |
+
f'<meta property="og:description" content="{html.escape(SITE_DESC, quote=True)}">') + """<style>
|
| 1548 |
+
.cs-tt-badge { display:inline-block; background:#e5f6ec; color:#17703f; font-weight:800; font-size:11.5px;
|
| 1549 |
+
letter-spacing:.06em; border-radius:99px; padding:4px 11px; margin-bottom:8px; }
|
| 1550 |
+
.cs-tt-price { margin-top:12px; font-size:15px; color:#1b2a6b; }
|
| 1551 |
+
.cs-tt-price b { font-size:22px; color:#3047b8; }
|
| 1552 |
+
.cs-tt-ticks { list-style:none !important; padding:0 !important; margin:10px 0 0 !important; display:flex;
|
| 1553 |
+
flex-wrap:wrap; gap:6px 18px; font-size:13.5px; color:#2c3350; }
|
| 1554 |
+
.cs-tt-ticks li { list-style:none !important; margin:0 !important; padding:0 !important; }
|
| 1555 |
+
.cs-tt-ticks li::marker { content:"" !important; }
|
| 1556 |
""" + SP.CSS + """
|
| 1557 |
#cs-go-pricing, #cs-go-account, #cs-go-formatter, #cs-go-finder, #cs-stop-srv, #cs-go-rephrase-text, #cs-go-rephrase-doc, #cs-go-unlock-smart, #cs-go-unlock-hum, .cs-hidden-nav { display: none !important; }
|
| 1558 |
a.cs-up-go { text-decoration: none !important; display: inline-block; }
|
|
|
|
| 2092 |
|
| 2093 |
GOTO_ACCOUNT = []
|
| 2094 |
|
| 2095 |
+
with gr.Blocks(title=SITE_TITLE, theme=theme, css=CSS + UI.css() + FND.CSS, js=FORCE_LIGHT,
|
| 2096 |
head=HEAD) as demo:
|
| 2097 |
user_state = gr.State(None)
|
| 2098 |
TOOLS_UI["user"] = user_state # the formatter / finder log their runs under the signed-in user
|
|
|
|
| 2122 |
sp_force = gr.Button("rephrase", elem_id="cs-go-rephrase-text", elem_classes="cs-hidden-nav", scale=0)
|
| 2123 |
sd_force = gr.Button("rephrase", elem_id="cs-go-rephrase-doc", elem_classes="cs-hidden-nav", scale=0)
|
| 2124 |
|
| 2125 |
+
with gr.Tabs(elem_id="cs-nav", selected="turnitin") as nav:
|
| 2126 |
+
# ============================ SMART HUMANIZE ============================
|
| 2127 |
+
# ============================ TURNITIN REPORT (the site's front door) ============================
|
| 2128 |
+
with gr.Tab("Turnitin Report", id="turnitin"):
|
| 2129 |
+
gr.HTML('<div class="cs-intro cs-hero cs-tt-hero"><div class="cs-tt-badge">REAL TURNITIN · NOT AN ESTIMATE'
|
| 2130 |
+
'</div><h2>See your <em>Turnitin report</em> before your university does</h2>'
|
| 2131 |
+
'<p>Upload your paper and get the same <b>AI-writing report</b> and <b>similarity report</b> '
|
| 2132 |
+
'your institution sees, as PDFs, usually in 2–5 minutes. Your paper is <b>not saved to the '
|
| 2133 |
+
'Turnitin repository</b>, so you can still submit it afterwards.</p>'
|
| 2134 |
+
'<div class="cs-flow"><span><i>1</i>Upload your paper</span><span><i>2</i>Turnitin checks it '
|
| 2135 |
+
'(2–5 min)</span><span><i>3</i>Download AI + similarity PDFs</span><span><i>4</i>Flagged? Fix it '
|
| 2136 |
+
'with Smart Humanize</span></div>'
|
| 2137 |
+
f'<div class="cs-tt-price"><b>{W.inr(W.usual_price("turnitin", 0))}</b> per document · any '
|
| 2138 |
+
'length · paid from your wallet · nothing is charged if a report cannot be produced</div>'
|
| 2139 |
+
'<ul class="cs-tt-ticks"><li>✓ AI-writing percentage with highlighted passages</li>'
|
| 2140 |
+
'<li>✓ Similarity percentage with matched sources</li><li>✓ No repository: safe to submit later'
|
| 2141 |
+
'</li><li>✓ Word, PDF or text files</li></ul></div>')
|
| 2142 |
+
_, tt_open, tt_lockbtn = lock_gate("Turnitin reports")
|
| 2143 |
+
GOTO_ACCOUNT.append(tt_lockbtn)
|
| 2144 |
+
with tt_open:
|
| 2145 |
+
with gr.Row(equal_height=False):
|
| 2146 |
+
with gr.Column(scale=1, elem_classes="cs-card"):
|
| 2147 |
+
tt_in = gr.File(label="Your paper (.docx, .pdf, .txt)", file_types=[".docx", ".pdf", ".txt"],
|
| 2148 |
+
type="filepath")
|
| 2149 |
+
tt_btn = gr.Button(f"Get Turnitin report — {W.inr(W.usual_price('turnitin', 0))}",
|
| 2150 |
+
variant="primary", size="lg")
|
| 2151 |
+
# (written as HTML: the status helpers would hide the word Turnitin)
|
| 2152 |
+
tt_status = gr.HTML('<div class="cs-status cs-idle">Upload your paper and press <b>Get '
|
| 2153 |
+
'Turnitin report</b>. The price is taken from your wallet only when the '
|
| 2154 |
+
'report is ready.</div>')
|
| 2155 |
+
with gr.Column(scale=1, elem_classes="cs-card"):
|
| 2156 |
+
tt_files = gr.File(label="Your Turnitin report (PDF)", file_count="multiple",
|
| 2157 |
+
interactive=False)
|
| 2158 |
+
tt_dl = gr.HTML()
|
| 2159 |
+
tt_to_smart = gr.Button("AI flagged? Lower it with Smart Humanize →")
|
| 2160 |
+
gr.HTML('<div class="cs-gauge-cap" style="text-align:left">Smart Humanize rewrites only the '
|
| 2161 |
+
'AI-flagged sentences of your Word file and keeps your layout, citations and '
|
| 2162 |
+
'numbers. Then check it here again.</div>')
|
| 2163 |
+
|
| 2164 |
# ============================ SMART HUMANIZE ============================
|
| 2165 |
with gr.Tab("Smart Humanize", id="smart"):
|
| 2166 |
+
gr.HTML('<div class="cs-intro cs-hero"><h2>Turnitin flagged it? Make it read as <em>your own</em></h2>'
|
| 2167 |
'<p>Drop your Word file and the rest is automatic: AI-sounding sentences are found, rewritten and '
|
| 2168 |
'checked again until the score is as low as it can safely go. Numbers, citations, technical '
|
| 2169 |
'terms and your layout stay exactly as they are.</p>'
|
|
|
|
| 2218 |
sd_status = gr.HTML(H.status_idle("Drop your .docx on the left. It starts by itself; nothing to press or set."))
|
| 2219 |
sd_file = gr.File(label="Download humanized .docx", interactive=False)
|
| 2220 |
sd_dl = gr.HTML()
|
| 2221 |
+
sd_to_tt = gr.Button("Check the humanized file with Turnitin →")
|
| 2222 |
sd_pr_btn = gr.Button("Final check & proofread (keeps the AI score)", variant="secondary")
|
| 2223 |
gr.Markdown("<small>After humanizing: one last full check of the whole document in a "
|
| 2224 |
"single pass: grammar, unclear sentences, academic wording, flow and "
|
|
|
|
| 2334 |
dd_to_smart = gr.Button("Humanize this .docx →")
|
| 2335 |
with gr.Column(scale=2):
|
| 2336 |
dd_html = gr.HTML()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2337 |
|
| 2338 |
# ============================ HUMANIZER ============================
|
| 2339 |
with gr.Tab("Humanizer", id="humanize", visible=False): # Smart Humanize includes this engine
|
|
|
|
| 2711 |
for b in GOTO_ACCOUNT + [top_signin]:
|
| 2712 |
b.click(lambda: gr.Tabs(selected="account"), None, nav, **HID)
|
| 2713 |
dp_to_smart.click(lambda t: (gr.Tabs(selected="smart"), t), dp_in, [nav, sp_in], **HID)
|
| 2714 |
+
# the report's PDFs are not the paper: hand over the uploaded Word file
|
| 2715 |
+
tt_to_smart.click(lambda f: (gr.Tabs(selected="smart"),
|
| 2716 |
+
f if f and str(f).lower().endswith(".docx") else None), tt_in, [nav, sd_in], **HID)
|
| 2717 |
+
sd_to_tt.click(lambda f: (gr.Tabs(selected="turnitin"), f), sd_file, [nav, tt_in], **HID)
|
| 2718 |
dd_to_smart.click(lambda f: (gr.Tabs(selected="smart"), f if f and str(f).lower().endswith(".docx") else None),
|
| 2719 |
dd_in, [nav, sd_in], **HID)
|
| 2720 |
hp_to_det.click(lambda t: (gr.Tabs(selected="detect"), t), hp_out, [nav, dp_in], **HID)
|
site_pages.py
CHANGED
|
@@ -25,6 +25,8 @@ WHATSAPP_URL = f"https://wa.me/{PHONE_DIGITS}?text=" + urllib.parse.quote(
|
|
| 25 |
"Hello CS Software Solutions, I have a question about the CS AI Writing Suite.")
|
| 26 |
|
| 27 |
SERVICES = [
|
|
|
|
|
|
|
| 28 |
("🎓", "PhD & research support",
|
| 29 |
"Topic selection, synopsis and proposal writing, literature reviews, thesis chapters and viva preparation."),
|
| 30 |
("📊", "Statistical analysis",
|
|
|
|
| 25 |
"Hello CS Software Solutions, I have a question about the CS AI Writing Suite.")
|
| 26 |
|
| 27 |
SERVICES = [
|
| 28 |
+
("📑", "Turnitin reports",
|
| 29 |
+
"Real Turnitin AI-writing and similarity reports as PDFs in minutes, not saved to the Turnitin repository."),
|
| 30 |
("🎓", "PhD & research support",
|
| 31 |
"Topic selection, synopsis and proposal writing, literature reviews, thesis chapters and viva preparation."),
|
| 32 |
("📊", "Statistical analysis",
|
wallet.py
CHANGED
|
@@ -378,14 +378,15 @@ def profit_report(days=30):
|
|
| 378 |
def pricing_html(free_note=""):
|
| 379 |
"""The Pricing page: pay as you go from a prepaid wallet, with the usual price of common jobs."""
|
| 380 |
import html as _h
|
| 381 |
-
rows = [("
|
|
|
|
| 382 |
("Smart Humanize, full paper (fast engine)", "fast", 2500),
|
| 383 |
("Smart Humanize, long paper", "smart", 5000),
|
| 384 |
("Smart Humanize, thesis chapter", "smart", 10000),
|
| 385 |
("AI detector report (beyond the free ones)", "detector", 3000),
|
| 386 |
("Proofread", "proofread", 3000)]
|
| 387 |
-
body = "".join(f"<tr><td>{_h.escape(t)}</td><td>{w:,} words</td>
|
| 388 |
-
f"</td></tr>" for t, k, w in rows)
|
| 389 |
tops = " · ".join(inr(x * 100) for x in TOPUPS)
|
| 390 |
return (f'<div class="cs-prices" style="max-width:900px;margin:0 auto;display:block">'
|
| 391 |
f'<div class="cs-price cs-featured" style="max-width:none"><div class="cs-pop">Pay as you go</div>'
|
|
|
|
| 378 |
def pricing_html(free_note=""):
|
| 379 |
"""The Pricing page: pay as you go from a prepaid wallet, with the usual price of common jobs."""
|
| 380 |
import html as _h
|
| 381 |
+
rows = [("Real Turnitin report: AI-writing + similarity PDFs", "turnitin", 0),
|
| 382 |
+
("Smart Humanize, short paper (fast engine)", "fast", 1000),
|
| 383 |
("Smart Humanize, full paper (fast engine)", "fast", 2500),
|
| 384 |
("Smart Humanize, long paper", "smart", 5000),
|
| 385 |
("Smart Humanize, thesis chapter", "smart", 10000),
|
| 386 |
("AI detector report (beyond the free ones)", "detector", 3000),
|
| 387 |
("Proofread", "proofread", 3000)]
|
| 388 |
+
body = "".join(f"<tr><td>{_h.escape(t)}</td><td>{'any length' if k in FIXED else f'{w:,} words'}</td>"
|
| 389 |
+
f"<td><b>{'' if k in FIXED else 'about '}{inr(usual_price(k, w))}</b></td></tr>" for t, k, w in rows)
|
| 390 |
tops = " · ".join(inr(x * 100) for x in TOPUPS)
|
| 391 |
return (f'<div class="cs-prices" style="max-width:900px;margin:0 auto;display:block">'
|
| 392 |
f'<div class="cs-price cs-featured" style="max-width:none"><div class="cs-pop">Pay as you go</div>'
|