shukdevdatta123 commited on
Commit
1f966f9
·
verified ·
1 Parent(s): d0acc10

Create ex.txt

Browse files
Files changed (1) hide show
  1. ex.txt +505 -0
ex.txt ADDED
@@ -0,0 +1,505 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import streamlit as st
3
+ import PyPDF2
4
+ import openai
5
+ import faiss
6
+ import os
7
+ import numpy as np
8
+ from sklearn.feature_extraction.text import TfidfVectorizer
9
+ from sklearn.metrics.pairwise import cosine_similarity
10
+ from io import StringIO
11
+
12
+ # Function to extract text from a PDF file
13
+ def extract_text_from_pdf(pdf_file):
14
+ reader = PyPDF2.PdfReader(pdf_file)
15
+ text = ""
16
+ for page in reader.pages:
17
+ text += page.extract_text()
18
+ return text
19
+
20
+ # Function to generate embeddings for a piece of text
21
+ def get_embeddings(text, model="text-embedding-ada-002"):
22
+ response = openai.Embedding.create(input=[text], model=model)
23
+ return response['data'][0]['embedding']
24
+
25
+ # Function to search for similar content
26
+ def search_similar(query_embedding, index, stored_texts, top_k=3):
27
+ distances, indices = index.search(np.array([query_embedding]), top_k)
28
+ results = [(stored_texts[i], distances[0][idx]) for idx, i in enumerate(indices[0])]
29
+ return results
30
+
31
+ # Function to generate code based on a prompt
32
+ def generate_code_from_prompt(prompt, model="gpt-4o-mini"):
33
+ response = openai.ChatCompletion.create(
34
+ model=model,
35
+ messages=[{"role": "user", "content": prompt}]
36
+ )
37
+ return response['choices'][0]['message']['content']
38
+
39
+ # Function to save code to a .txt file
40
+ def save_code_to_file(code, filename="generated_code.txt"):
41
+ with open(filename, "w") as f:
42
+ f.write(code)
43
+
44
+ # Function to generate AI-based study notes and summaries
45
+ def generate_summary(text):
46
+ prompt = f"Summarize the following text into key points:\n\n{text}"
47
+ response = openai.ChatCompletion.create(
48
+ model="gpt-4o-mini",
49
+ messages=[{"role": "user", "content": prompt}]
50
+ )
51
+ return response['choices'][0]['message']['content']
52
+
53
+ # Function to fix bugs in code
54
+ def fix_code_bugs(buggy_code, model="gpt-4o-mini"):
55
+ prompt = f"The following code has bugs or issues. Please identify and fix the problems. If possible, provide explanations for the changes made.\n\nBuggy Code:\n{buggy_code}\n\nFixed Code:"
56
+ response = openai.ChatCompletion.create(
57
+ model=model,
58
+ messages=[{"role": "user", "content": prompt}]
59
+ )
60
+ return response['choices'][0]['message']['content']
61
+
62
+ # Function to generate AI-based mathematical solutions
63
+ def generate_math_solution(query):
64
+ prompt = f"Explain and solve the following mathematical problem step by step: {query}"
65
+ response = openai.ChatCompletion.create(
66
+ model="gpt-3.5-turbo",
67
+ messages=[{"role": "user", "content": prompt}]
68
+ )
69
+ return response['choices'][0]['message']['content']
70
+
71
+ from PIL import Image # Required for local image files
72
+
73
+ # Streamlit app starts here
74
+ st.set_page_config(page_title="AI Assistance", page_icon=":robot:", layout="wide")
75
+
76
+ # Display a logo or icon
77
+ image = Image.open("14313824.png") # Path to your image file
78
+ st.image(image, width=200) # You can adjust the width as needed
79
+
80
+ # Streamlit app starts here
81
+ st.title("AI Assistance")
82
+
83
+ # Input OpenAI API key
84
+ openai_api_key = st.text_input("Enter your OpenAI API key:", type="password")
85
+
86
+ if openai_api_key:
87
+ openai.api_key = openai_api_key
88
+
89
+ # Sidebar to toggle between Course Query Assistant, Code Generator, Bug Fixer, etc.
90
+ st.sidebar.title("Select Mode")
91
+ mode = st.sidebar.radio("Choose an option", (
92
+ "Course Query Assistant",
93
+ "Code Generator",
94
+ "AI Chatbot Tutor",
95
+ "AI Study Notes & Summaries",
96
+ "Code Bug Fixer",
97
+ "Mathematics Assistant", # Added option for Math
98
+ "Biology Assistant", # Added option for Biology
99
+ "Chemistry Assistant", # Added option for Chemistry
100
+ "Physics Assistant", # Added option for Physics
101
+ "Voice Chat",
102
+ "Image Chat",
103
+ "English To Japanese",
104
+ "Text to Image Generator",
105
+ "Graph Tutorial",
106
+ "Text-To-Diagram-Generator"
107
+ ))
108
+
109
+ # Add Contact information in the sidebar
110
+ st.sidebar.markdown("""
111
+ ## Contact
112
+
113
+ For any questions or issues, please contact:
114
+
115
+ - **Email**: [shukdevdatta@gmail.com](mailto:shukdevdatta@gmail.com)
116
+ - **GitHub**: [Click here to access the Github Profile](https://github.com/shukdevtroy)
117
+ - **WhatsApp**: [Click here to chat](https://wa.me/+8801719296601)
118
+ - **HuggingFace Profile**: [Click here to access the HuggingFace Profile](https://huggingface.co/shukdevdatta123)
119
+ """)
120
+
121
+ if mode == "Course Query Assistant":
122
+ st.header("Course Query Assistant")
123
+
124
+ # Display image/logo in the "Course Query Assistant" section (optional)
125
+ course_query_image = Image.open("Capture.PNG") # Ensure the file is in the correct directory
126
+ st.image(course_query_image, width=150) # Adjust the size as per preference
127
+
128
+ # Upload course materials
129
+ uploaded_files = st.file_uploader("Upload Course Materials (PDFs)", type=["pdf"], accept_multiple_files=True)
130
+
131
+ if uploaded_files:
132
+ st.write("Processing uploaded course materials...")
133
+
134
+ # Extract text and generate embeddings for all uploaded PDFs
135
+ course_texts = []
136
+ for uploaded_file in uploaded_files:
137
+ text = extract_text_from_pdf(uploaded_file)
138
+ course_texts.append(text)
139
+
140
+ # Combine all course materials into one large text
141
+ combined_text = " ".join(course_texts)
142
+
143
+ # Split combined text into smaller chunks for embedding (max tokens ~1000)
144
+ chunks = [combined_text[i:i+1000] for i in range(0, len(combined_text), 1000)]
145
+
146
+ # Generate embeddings for all chunks
147
+ embeddings = [get_embeddings(chunk) for chunk in chunks]
148
+
149
+ # Convert the list of embeddings into a NumPy array (shape: [num_chunks, embedding_size])
150
+ embeddings_np = np.array(embeddings).astype("float32")
151
+
152
+ # Create a FAISS index for similarity search
153
+ index = faiss.IndexFlatL2(len(embeddings_np[0])) # Use the length of the embedding vectors for the dimension
154
+ index.add(embeddings_np)
155
+
156
+ st.write("Course materials have been processed and indexed.")
157
+
158
+ # User query
159
+ query = st.text_input("Enter your question about the course materials:")
160
+
161
+ if query:
162
+ # Generate embedding for the query
163
+ query_embedding = get_embeddings(query)
164
+
165
+ # Search for similar chunks in the FAISS index
166
+ results = search_similar(query_embedding, index, chunks)
167
+
168
+ # Create the context for the GPT prompt
169
+ context = "\n".join([result[0] for result in results])
170
+ modified_prompt = f"Context: {context}\n\nQuestion: {query}\n\nProvide a detailed answer based on the context."
171
+
172
+ # Get the GPT-4 response
173
+ response = openai.ChatCompletion.create(
174
+ model="gpt-4o-mini", # Update to GPT-4 (or your desired model)
175
+ messages=[{"role": "user", "content": modified_prompt}]
176
+ )
177
+
178
+ # Get the response content
179
+ response_content = response['choices'][0]['message']['content']
180
+
181
+ # Display the response in Streamlit (Intelligent Reply)
182
+ st.write("### Intelligent Reply:")
183
+ st.write(response_content)
184
+
185
+ elif mode == "Code Generator":
186
+ st.header("Code Generator")
187
+
188
+ # Display image/logo in the "Course Query Assistant" section (optional)
189
+ codegen = Image.open("9802381.png") # Ensure the file is in the correct directory
190
+ st.image(codegen, width=150) # Adjust the size as per preference
191
+
192
+ # Code generation prompt input
193
+ code_prompt = st.text_area("Describe the code you want to generate:",
194
+ "e.g., Write a Python program that generates Fibonacci numbers.")
195
+
196
+ if st.button("Generate Code"):
197
+ if code_prompt:
198
+ with st.spinner("Generating code..."):
199
+ # Generate code using GPT-4
200
+ generated_code = generate_code_from_prompt(code_prompt)
201
+
202
+ # Clean the generated code to ensure only code is saved (removing comments or additional text)
203
+ clean_code = "\n".join([line for line in generated_code.splitlines() if not line.strip().startswith("#")])
204
+
205
+ # Save the clean code to a file
206
+ save_code_to_file(clean_code)
207
+
208
+ # Display the generated code
209
+ st.write("### Generated Code:")
210
+ st.code(clean_code, language="python")
211
+
212
+ # Provide a download link for the generated code
213
+ with open("generated_code.txt", "w") as f:
214
+ f.write(clean_code)
215
+
216
+ st.download_button(
217
+ label="Download Generated Code",
218
+ data=open("generated_code.txt", "rb").read(),
219
+ file_name="generated_code.txt",
220
+ mime="text/plain"
221
+ )
222
+ else:
223
+ st.error("Please provide a prompt to generate the code.")
224
+
225
+ elif mode == "AI Chatbot Tutor":
226
+ st.header("AI Chatbot Tutor")
227
+
228
+ # Display image/logo in the "Course Query Assistant" section (optional)
229
+ aitut = Image.open("910372.png") # Ensure the file is in the correct directory
230
+ st.image(aitut, width=150) # Adjust the size as per preference
231
+
232
+ # Chat interface for the AI tutor
233
+ chat_history = []
234
+
235
+ def chat_with_bot(query):
236
+ chat_history.append({"role": "user", "content": query})
237
+ response = openai.ChatCompletion.create(
238
+ model="gpt-4o-mini",
239
+ messages=chat_history
240
+ )
241
+ chat_history.append({"role": "assistant", "content": response['choices'][0]['message']['content']})
242
+ return response['choices'][0]['message']['content']
243
+
244
+ user_query = st.text_input("Ask a question:")
245
+
246
+ if user_query:
247
+ with st.spinner("Getting answer..."):
248
+ bot_response = chat_with_bot(user_query)
249
+ st.write(f"### AI Response: {bot_response}")
250
+
251
+ elif mode == "AI Study Notes & Summaries":
252
+ st.header("AI Study Notes & Summaries")
253
+
254
+ # Display image/logo in the "Course Query Assistant" section (optional)
255
+ aisum = Image.open("sum.png") # Ensure the file is in the correct directory
256
+ st.image(aisum, width=150) # Adjust the size as per preference
257
+
258
+ # Upload course materials for summarization
259
+ uploaded_files_for_summary = st.file_uploader("Upload Course Materials (PDFs) for Summarization", type=["pdf"], accept_multiple_files=True)
260
+
261
+ if uploaded_files_for_summary:
262
+ st.write("Generating study notes and summaries...")
263
+
264
+ # Extract text from PDFs
265
+ all_text = ""
266
+ for uploaded_file in uploaded_files_for_summary:
267
+ text = extract_text_from_pdf(uploaded_file)
268
+ all_text += text
269
+
270
+ # Generate summary using AI
271
+ summary = generate_summary(all_text)
272
+
273
+ # Display the summary
274
+ st.write("### AI-Generated Summary:")
275
+ st.write(summary)
276
+
277
+ elif mode == "Code Bug Fixer":
278
+ st.header("Code Bug Fixer")
279
+
280
+ # Display image/logo in the "Course Query Assistant" section (optional)
281
+ aibug = Image.open("bug.png") # Ensure the file is in the correct directory
282
+ st.image(aibug, width=150) # Adjust the size as per preference
283
+
284
+ # User input for buggy code
285
+ buggy_code = st.text_area("Enter your buggy code here:")
286
+
287
+ if st.button("Fix Code"):
288
+ if buggy_code:
289
+ with st.spinner("Fixing code..."):
290
+ # Fix bugs using GPT-4
291
+ fixed_code = fix_code_bugs(buggy_code)
292
+
293
+ # Display the fixed code
294
+ st.write("### Fixed Code:")
295
+ st.code(fixed_code, language="python")
296
+
297
+ # Provide a download link for the fixed code
298
+ with open("fixed_code.txt", "w") as f:
299
+ f.write(fixed_code)
300
+
301
+ st.download_button(
302
+ label="Download Fixed Code",
303
+ data=open("fixed_code.txt", "rb").read(),
304
+ file_name="fixed_code.txt",
305
+ mime="text/plain"
306
+ )
307
+ else:
308
+ st.error("Please enter some buggy code to fix.")
309
+
310
+ elif mode == "Mathematics Assistant":
311
+ st.header("Mathematics Assistant")
312
+
313
+ # Display image/logo in the "Mathematics Assistant" section (optional)
314
+ math_icon = Image.open("math_icon.PNG") # Ensure the file is in the correct directory
315
+ st.image(math_icon, width=150) # Adjust the size as per preference
316
+
317
+ # User input for math questions
318
+ math_query = st.text_input("Ask a mathematics-related question:")
319
+
320
+ if st.button("Solve Problem"):
321
+ if math_query:
322
+ with st.spinner("Generating solution..."):
323
+ # Generate the solution using GPT-4
324
+ solution = generate_math_solution(math_query)
325
+
326
+ # Render the solution with LaTeX for mathematical notations
327
+ formatted_solution = f"""
328
+ ### Solution to the Problem
329
+ **Problem:** {math_query}
330
+ **Solution:**
331
+ {solution}
332
+ """
333
+
334
+ st.markdown(formatted_solution)
335
+ else:
336
+ st.error("Please enter a math problem to solve.")
337
+
338
+ # **New Section: Biology Assistant**
339
+ elif mode == "Biology Assistant":
340
+ st.header("Biology Assistant")
341
+
342
+ # Display image/logo in the "Biology Assistant" section (optional)
343
+ bio_icon = Image.open("bio_icon.PNG") # Ensure the file is in the correct directory
344
+ st.image(bio_icon, width=150) # Adjust the size as per preference
345
+
346
+ # User input for biology questions
347
+ bio_query = st.text_input("Ask a biology-related question:")
348
+
349
+ if bio_query:
350
+ with st.spinner("Getting answer..."):
351
+ prompt = f"Answer the following biology question: {bio_query}"
352
+ response = openai.ChatCompletion.create(
353
+ model="gpt-4o-mini",
354
+ messages=[{"role": "user", "content": prompt}]
355
+ )
356
+ answer = response['choices'][0]['message']['content']
357
+ st.write(f"### Answer: {answer}")
358
+
359
+ # **New Section: Chemistry Assistant**
360
+ elif mode == "Chemistry Assistant":
361
+ st.header("Chemistry Assistant")
362
+
363
+ # Display image/logo in the "Chemistry Assistant" section (optional)
364
+ chem_icon = Image.open("chem.PNG") # Ensure the file is in the correct directory
365
+ st.image(chem_icon, width=150) # Adjust the size as per preference
366
+
367
+ # User input for chemistry questions
368
+ chem_query = st.text_input("Ask a chemistry-related question:")
369
+
370
+ if chem_query:
371
+ with st.spinner("Getting answer..."):
372
+ prompt = f"Answer the following chemistry question: {chem_query}"
373
+ response = openai.ChatCompletion.create(
374
+ model="gpt-4o-mini",
375
+ messages=[{"role": "user", "content": prompt}]
376
+ )
377
+ answer = response['choices'][0]['message']['content']
378
+ st.write(f"### Answer: {answer}")
379
+
380
+ # **New Section: Physics Assistant**
381
+ elif mode == "Physics Assistant":
382
+ st.header("Physics Assistant")
383
+
384
+ # Display image/logo in the "Physics Assistant" section (optional)
385
+ phys_icon = Image.open("physics_icon.PNG") # Ensure the file is in the correct directory
386
+ st.image(phys_icon, width=150) # Adjust the size as per preference
387
+
388
+ # User input for physics questions
389
+ phys_query = st.text_input("Ask a physics-related question:")
390
+
391
+ if phys_query:
392
+ with st.spinner("Getting answer..."):
393
+ prompt = f"Answer the following physics question: {phys_query}"
394
+ response = openai.ChatCompletion.create(
395
+ model="gpt-3.5-turbo",
396
+ messages=[{"role": "user", "content": prompt}]
397
+ )
398
+ answer = response['choices'][0]['message']['content']
399
+ st.write(f"### Answer: {answer}")
400
+
401
+ # **New Section: Voice Chat**
402
+ elif mode == "Voice Chat":
403
+ st.header("Voice Chat")
404
+
405
+ # Display a description or instructions
406
+ st.write("Click the button below to go to the Voice Chat.")
407
+
408
+ # Display image/logo in the "Physics Assistant" section (optional)
409
+ gif = "200w.gif" # Ensure the file is in the correct directory
410
+ st.image(gif, use_container_width=50) # Adjust the size as per preference
411
+
412
+ # Button to navigate to the external voice chat link
413
+ if st.button("Go to Voice Chat"):
414
+ st.write("Redirecting to the voice chat...") # You can customize this message
415
+ st.markdown(f'<a href="https://shukdevdatta123-voicechat.hf.space" target="_blank">Go to Voice Chat</a>', unsafe_allow_html=True)
416
+
417
+ # **New Section: Image Chat**
418
+ elif mode == "Image Chat":
419
+
420
+ # Display image/logo in the "Physics Assistant" section (optional)
421
+ imgc = Image.open("i.jpg") # Ensure the file is in the correct directory
422
+ st.image(imgc, width=150) # Adjust the size as per preference
423
+
424
+ st.header("Image Chat")
425
+
426
+ # Display a description or instructions
427
+ st.write("Click the button below to go to the Image Chat.")
428
+
429
+ # Display image/logo in the "Physics Assistant" section (optional)
430
+ gif = "200w.gif" # Ensure the file is in the correct directory
431
+ st.image(gif, use_container_width=50) # Adjust the size as per preference
432
+
433
+ # Button to navigate to the external voice chat link
434
+ if st.button("Go to Image Chat"):
435
+ st.write("Redirecting to the image chat...") # You can customize this message
436
+ st.markdown(f'<a href="https://imagechat2278.streamlit.app/" target="_blank">Go to Image Chat</a>', unsafe_allow_html=True)
437
+
438
+ # Button to navigate to the alternative app (alternative)
439
+ if st.button("Go to Image Chat (Alternative App)"):
440
+ st.write("Redirecting to the alternative image chat...") # You can customize this message
441
+ st.markdown(f'<a href="https://imagechat.onrender.com/" target="_blank">Go to Image Chat (Alternative App)</a>', unsafe_allow_html=True)
442
+
443
+ # **New Section: English To Japanese**
444
+ elif mode == "English To Japanese":
445
+ st.header("English To Japanese")
446
+
447
+ # Display a description or instructions
448
+ st.write("Click the button below to go to the English To Japanese Translator.")
449
+
450
+
451
+ gif = "200w.gif" # Ensure the file is in the correct directory
452
+ st.image(gif, use_container_width=150) # Adjust the size as per preference
453
+
454
+ # Button to navigate to the external voice chat link
455
+ if st.button("Go to English To Japanese Translator"):
456
+ st.write("Redirecting to the English To Japanese Translator...") # You can customize this message
457
+ st.markdown(f'<a href="https://shukdevdatta123-engtojap-2-0.hf.space" target="_blank">Go to English To Japanese Translator</a>', unsafe_allow_html=True)
458
+
459
+ # **New Section: Text to Image Generator**
460
+ elif mode == "Text to Image Generator":
461
+ st.header("Text to Image Generator")
462
+
463
+ # Display a description or instructions
464
+ st.write("Click the button below to go to the Text to Image Generator.")
465
+
466
+
467
+ gif = "200w.gif" # Ensure the file is in the correct directory
468
+ st.image(gif, use_container_width=150) # Adjust the size as per preference
469
+
470
+ # Button to navigate to the external voice chat link
471
+ if st.button("Go to Text to Image Generator"):
472
+ st.write("Redirecting to the Text to Image Generator...") # You can customize this message
473
+ st.markdown(f'<a href="https://shukdevdatta123-image-generator-dall-e3.hf.space" target="_blank">Go to Text to Image Generator</a>', unsafe_allow_html=True)
474
+
475
+ # **New Section: Graph Tutorial**
476
+ elif mode == "Graph Tutorial":
477
+ st.header("Graph Tutorial")
478
+
479
+ # Display a description or instructions
480
+ st.write("Click the button below to go to Graph Tutorial.")
481
+
482
+
483
+ gif = "200w.gif" # Ensure the file is in the correct directory
484
+ st.image(gif, use_container_width=150) # Adjust the size as per preference
485
+
486
+ # Button to navigate to the external voice chat link
487
+ if st.button("Go to Graph Tutorial"):
488
+ st.write("Redirecting to Graph Tutorial...") # You can customize this message
489
+ st.markdown(f'<a href="https://shukdevdatta123-networkx-tutorial.hf.space" target="_blank">Go to Graph Tutorial</a>', unsafe_allow_html=True)
490
+
491
+ # **New Section: Text-To-Diagram-Generator**
492
+ elif mode == "Text-To-Diagram-Generator":
493
+ st.header("Text-To-Diagram-Generator")
494
+
495
+ # Display a description or instructions
496
+ st.write("Click the button below to go to Text-To-Diagram-Generator.")
497
+
498
+
499
+ gif = "200w.gif" # Ensure the file is in the correct directory
500
+ st.image(gif, use_container_width=150) # Adjust the size as per preference
501
+
502
+ # Button to navigate to the external voice chat link
503
+ if st.button("Go to Text-To-Diagram-Generator"):
504
+ st.write("Redirecting to Text-To-Diagram-Generator...") # You can customize this message
505
+ st.markdown(f'<a href="https://shukdevdatta123-text-2-diagram.hf.space" target="_blank">Go to Text-To-Diagram-Generator</a>', unsafe_allow_html=True)