Spaces:
Running
Running
Krishnan Palanisami
commited on
Commit
•
fb0e8e0
1
Parent(s):
1a8a65b
Update app.py
Browse files
app.py
CHANGED
@@ -97,415 +97,3 @@ def main():
|
|
97 |
if __name__ == "__main__":
|
98 |
main()
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
# import streamlit as st
|
103 |
-
# import wikipedia
|
104 |
-
# from haystack.document_stores import InMemoryDocumentStore
|
105 |
-
# from haystack.utils import clean_wiki_text, convert_files_to_docs
|
106 |
-
# from haystack.nodes import TfidfRetriever, FARMReader
|
107 |
-
# from haystack.pipelines import ExtractiveQAPipeline
|
108 |
-
# from main import print_qa, QuestionGenerator
|
109 |
-
# import torch
|
110 |
-
|
111 |
-
# def main():
|
112 |
-
# # Set the Streamlit app title
|
113 |
-
# st.title("Question Generation using Haystack and Streamlit")
|
114 |
-
|
115 |
-
# # Select the input type
|
116 |
-
# inputs = ["Input Paragraph", "Wikipedia Examples"]
|
117 |
-
# input_type = st.selectbox("Select an input type:", inputs, key="input_type")
|
118 |
-
|
119 |
-
# # Initialize wiki_text as an empty string (to avoid UnboundLocalError)
|
120 |
-
# wiki_text = """ Deep learning is the subset of machine learning methods based on artificial neural networks (ANNs) with representation learning. The adjective "deep" refers to the use of multiple layers in the network. Methods used can be either supervised, semi-supervised or unsupervised.Deep-learning architectures such as deep neural networks, deep belief networks, recurrent neural networks, convolutional neural networks and transformers have been applied to fields including computer vision, speech recognition, natural language processing, machine translation, bioinformatics, drug design, medical image analysis, climate science, material inspection and board game programs, where they have produced results comparable to and in some cases surpassing human expert performance.Artificial neural networks were inspired by information processing and distributed communication nodes in biological systems. ANNs have various differences from biological brains. Specifically, artificial neural networks tend to be static and symbolic, while the biological brain of most living organisms is dynamic (plastic) and analog. ANNs are generally seen as low quality models for brain function."""
|
121 |
-
|
122 |
-
# # Handle different input types
|
123 |
-
# if input_type == "Input Paragraph":
|
124 |
-
# # Allow user to input text paragraph
|
125 |
-
# wiki_text = st.text_area("Input paragraph:", height=200, key="input_paragraph")
|
126 |
-
|
127 |
-
# elif input_type == "Wikipedia Examples":
|
128 |
-
# # Define options for selecting the topic
|
129 |
-
# topics = ["Deep Learning", "Machine Learning"]
|
130 |
-
# selected_topic = st.selectbox("Select a topic:", topics, key="wiki_topic")
|
131 |
-
|
132 |
-
# # Retrieve Wikipedia content based on the selected topic
|
133 |
-
# if selected_topic:
|
134 |
-
# wiki = wikipedia.page(selected_topic)
|
135 |
-
# wiki_text = wiki.content
|
136 |
-
|
137 |
-
# # Display the retrieved Wikipedia content (optional)
|
138 |
-
# st.text_area("Retrieved Wikipedia content:", wiki_text, height=200, key="wiki_text")
|
139 |
-
|
140 |
-
# # Allow user to specify the number of questions to generate
|
141 |
-
# num_questions = st.slider("Number of questions to generate:", min_value=1, max_value=20, value=5, key="num_questions")
|
142 |
-
|
143 |
-
# # Allow user to specify the model to use
|
144 |
-
# model_options = ["deepset/roberta-base-squad2", "deepset/roberta-base-squad2-distilled", "bert-large-uncased-whole-word-masking-squad2", "deepset/flan-t5-xl-squad2"]
|
145 |
-
# model_name = st.selectbox("Select model:", model_options, key="model_name")
|
146 |
-
|
147 |
-
# # Button to generate questions
|
148 |
-
# if st.button("Generate Questions", key="generate_button"):
|
149 |
-
# # Initialize the document store
|
150 |
-
# with open('wiki_txt.txt', 'w', encoding='utf-8') as f:
|
151 |
-
# f.write(wiki_text)
|
152 |
-
# document_store = InMemoryDocumentStore()
|
153 |
-
# doc_dir = "/content"
|
154 |
-
# docs = convert_files_to_docs(dir_path=doc_dir, clean_func=clean_wiki_text, split_paragraphs=True)
|
155 |
-
# document_store.write_documents(docs)
|
156 |
-
# retriever = TfidfRetriever(document_store=document_store)
|
157 |
-
|
158 |
-
# # # Convert the input text paragraph or Wikipedia content into a document
|
159 |
-
# # document = {"content": wiki_text}
|
160 |
-
# # document_store.write_documents([document])
|
161 |
-
|
162 |
-
# # Initialize a TfidfRetriever
|
163 |
-
# # retriever = TfidfRetriever(document_store=document_store)
|
164 |
-
|
165 |
-
# # Initialize a FARMReader with the selected model
|
166 |
-
# reader = FARMReader(model_name_or_path=model_name, use_gpu=False)
|
167 |
-
|
168 |
-
# # Initialize the question generation pipeline
|
169 |
-
# pipe = ExtractiveQAPipeline(reader, retriever)
|
170 |
-
# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
171 |
-
|
172 |
-
# # Initialize the QuestionGenerator
|
173 |
-
# qg = QuestionGenerator()
|
174 |
-
|
175 |
-
# # Generate multiple-choice questions
|
176 |
-
# qa_list = qg.generate(wiki_text, num_questions=num_questions, answer_style='multiple_choice')
|
177 |
-
|
178 |
-
# # Display the generated questions and answers
|
179 |
-
# st.header("Generated Questions and Answers:")
|
180 |
-
# for idx, qa in enumerate(qa_list):
|
181 |
-
# # Display the question
|
182 |
-
# st.write(f"Question {idx + 1}: {qa['question']}")
|
183 |
-
|
184 |
-
# # Display the answer options
|
185 |
-
# if 'answer' in qa:
|
186 |
-
# for i, option in enumerate(qa['answer']):
|
187 |
-
# correct_marker = "(correct)" if option["correct"] else ""
|
188 |
-
# st.write(f"Option {i + 1}: {option['answer']} {correct_marker}")
|
189 |
-
|
190 |
-
# # Add a separator after each question-answer pair
|
191 |
-
# st.write("-" * 40)
|
192 |
-
|
193 |
-
# # Run the Streamlit app
|
194 |
-
# if __name__ == "__main__":
|
195 |
-
# main()
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
# # import streamlit as st
|
224 |
-
# # import wikipedia
|
225 |
-
# # from haystack.document_stores import InMemoryDocumentStore
|
226 |
-
# # from haystack.utils import clean_wiki_text, convert_files_to_docs
|
227 |
-
# # from haystack.nodes import TfidfRetriever, FARMReader
|
228 |
-
# # from haystack.pipelines import ExtractiveQAPipeline
|
229 |
-
# # from main import print_qa, QuestionGenerator
|
230 |
-
|
231 |
-
# # def main():
|
232 |
-
# # # Set the Streamlit app title
|
233 |
-
# # st.title("Question Generation using Haystack and Streamlit")
|
234 |
-
# # # select the input type
|
235 |
-
# # inputs = ["Input Paragraph", "Wikipedia Examples"]
|
236 |
-
# # input=st.selectbox("Select a Input Type :", inputs)
|
237 |
-
# # if(input=="Input Paragraph"):
|
238 |
-
# # # Allow user to input text paragraph
|
239 |
-
# # wiki_text = st.text_area("Input paragraph:", height=200)
|
240 |
-
|
241 |
-
# # # # Allow user to specify the number of questions to generate
|
242 |
-
# # # num_questions = st.slider("Number of questions to generate:", min_value=1, max_value=20, value=5)
|
243 |
-
|
244 |
-
# # # # Allow user to specify the model to use
|
245 |
-
# # # model_options = ["deepset/roberta-base-squad2", "deepset/roberta-base-squad2-distilled", "bert-large-uncased-whole-word-masking-squad2","deepset/flan-t5-xl-squad2"]
|
246 |
-
# # # model_name = st.selectbox("Select model:", model_options)
|
247 |
-
|
248 |
-
# # # # Button to generate questions
|
249 |
-
# # # if st.button("Generate Questions"):
|
250 |
-
# # # qno=0
|
251 |
-
|
252 |
-
# # # # Initialize the document store
|
253 |
-
# # # document_store = InMemoryDocumentStore()
|
254 |
-
|
255 |
-
# # # # Convert the input text paragraph into a document
|
256 |
-
# # # document = {"content": wiki_text}
|
257 |
-
# # # document_store.write_documents([document])
|
258 |
-
|
259 |
-
# # # # Initialize a TfidfRetriever
|
260 |
-
# # # retriever = TfidfRetriever(document_store=document_store)
|
261 |
-
|
262 |
-
# # # # Initialize a FARMReader with the selected model
|
263 |
-
# # # reader = FARMReader(model_name_or_path=model_name, use_gpu=False)
|
264 |
-
|
265 |
-
# # # # Initialize the question generation pipeline
|
266 |
-
# # # pipe = ExtractiveQAPipeline(reader, retriever)
|
267 |
-
|
268 |
-
# # # # Initialize the QuestionGenerator
|
269 |
-
# # # qg = QuestionGenerator()
|
270 |
-
|
271 |
-
# # # # Generate multiple-choice questions
|
272 |
-
# # # qa_list = qg.generate(
|
273 |
-
# # # wiki_text,
|
274 |
-
# # # num_questions=num_questions,
|
275 |
-
# # # answer_style='multiple_choice')
|
276 |
-
# # # print("QA List Structure:")
|
277 |
-
# # # # Display the generated questions and answers
|
278 |
-
# # # st.header("Generated Questions and Answers:")
|
279 |
-
# # # for qa in qa_list:
|
280 |
-
# # # opno=0
|
281 |
-
|
282 |
-
# # # # Display the question
|
283 |
-
# # # st.write(f"Question: {qno+1}{qa['question']}")
|
284 |
-
|
285 |
-
# # # # Display the answer options
|
286 |
-
# # # if 'answer' in qa:
|
287 |
-
# # # for idx, option in enumerate(qa['answer']):
|
288 |
-
# # # # Indicate if the option is correct
|
289 |
-
# # # correct_marker = "(correct)" if option["correct"] else ""
|
290 |
-
# # # st.write(f"Option {idx + 1}: {option['answer']} {correct_marker}")
|
291 |
-
|
292 |
-
# # # # Add a separator after each question-answer pair
|
293 |
-
# # # st.write("-" * 40)
|
294 |
-
|
295 |
-
# # if(input == "Wikipedia Examples"):
|
296 |
-
# # # Define options for selecting the topic
|
297 |
-
# # topics = ["Deep Learning", "MachineLearning"]
|
298 |
-
# # selected_topic = st.selectbox("Select a topic:", topics)
|
299 |
-
|
300 |
-
# # # Retrieve Wikipedia content based on the selected topic
|
301 |
-
# # if selected_topic:
|
302 |
-
# # wiki = wikipedia.page(selected_topic)
|
303 |
-
# # wiki_text = wiki.content
|
304 |
-
|
305 |
-
# # # Display the retrieved Wikipedia content in a text area (optional)
|
306 |
-
# # st.text_area("Retrieved Wikipedia content:", wiki_text, height=200)
|
307 |
-
|
308 |
-
# # # # Allow user to specify the number of questions to generate
|
309 |
-
# # # num_questions = st.slider("Number of questions to generate:", min_value=1, max_value=20, value=5)
|
310 |
-
|
311 |
-
# # # # Allow user to specify the model to use
|
312 |
-
# # # model_options = ["deepset/roberta-base-squad2", "deepset/roberta-base-squad2-distilled", "bert-large-uncased-whole-word-masking-squad2","deepset/flan-t5-xl-squad2"]
|
313 |
-
# # # model_name = st.selectbox("Select model:", model_options)
|
314 |
-
|
315 |
-
# # # # Button to generate questions
|
316 |
-
# # # if st.button("Generate Questions"):
|
317 |
-
# # # # Initialize the document store
|
318 |
-
# # # document_store = InMemoryDocumentStore()
|
319 |
-
|
320 |
-
# # # # Convert the retrieved Wikipedia content into a document
|
321 |
-
# # # document = {"content": wiki_text}
|
322 |
-
# # # document_store.write_documents([document])
|
323 |
-
|
324 |
-
# # # # Initialize a TfidfRetriever
|
325 |
-
# # # retriever = TfidfRetriever(document_store=document_store)
|
326 |
-
|
327 |
-
# # # # Initialize a FARMReader with the selected model
|
328 |
-
# # # reader = FARMReader(model_name_or_path=model_name, use_gpu=False)
|
329 |
-
|
330 |
-
# # # # Initialize the ExtractiveQAPipeline
|
331 |
-
# # # pipeline = ExtractiveQAPipeline(reader, retriever)
|
332 |
-
|
333 |
-
# # # # Initialize the QuestionGenerator
|
334 |
-
# # # qg = QuestionGenerator()
|
335 |
-
|
336 |
-
# # # # Generate multiple-choice questions
|
337 |
-
# # # qa_list = qg.generate(
|
338 |
-
# # # wiki_text,
|
339 |
-
# # # num_questions=num_questions,
|
340 |
-
# # # answer_style='multiple_choice'
|
341 |
-
# # # )
|
342 |
-
|
343 |
-
# # # # Display the generated questions and answers
|
344 |
-
# # # st.header("Generated Questions and Answers:")
|
345 |
-
# # # for idx, qa in enumerate(qa_list):
|
346 |
-
# # # # Display the question
|
347 |
-
# # # st.write(f"Question {idx + 1}: {qa['question']}")
|
348 |
-
|
349 |
-
# # # # Display the answer options
|
350 |
-
# # # if 'answer' in qa:
|
351 |
-
# # # for i, option in enumerate(qa['answer']):
|
352 |
-
# # # correct_marker = "(correct)" if option["correct"] else ""
|
353 |
-
# # # st.write(f"Option {i + 1}: {option['answer']} {correct_marker}")
|
354 |
-
|
355 |
-
# # # # Add a separator after each question-answer pair
|
356 |
-
# # # st.write("-" * 40)
|
357 |
-
|
358 |
-
# # # Allow user to specify the number of questions to generate
|
359 |
-
# # num_questions = st.slider("Number of questions to generate:", min_value=1, max_value=20, value=5)
|
360 |
-
# # # Allow user to specify the model to use
|
361 |
-
# # model_options = ["deepset/roberta-base-squad2", "deepset/roberta-base-squad2-distilled", "bert-large-uncased-whole-word-masking-squad2","deepset/flan-t5-xl-squad2"]
|
362 |
-
# # model_name = st.selectbox("Select model:", model_options)
|
363 |
-
|
364 |
-
# # # Button to generate questions
|
365 |
-
# # if st.button("Generate Questions"):
|
366 |
-
# # qno=0
|
367 |
-
|
368 |
-
# # # Initialize the document store
|
369 |
-
# # document_store = InMemoryDocumentStore()
|
370 |
-
|
371 |
-
# # # Convert the input text paragraph into a document
|
372 |
-
# # document = {"content": wiki_text}
|
373 |
-
# # document_store.write_documents([document])
|
374 |
-
|
375 |
-
# # # Initialize a TfidfRetriever
|
376 |
-
# # retriever = TfidfRetriever(document_store=document_store)
|
377 |
-
|
378 |
-
# # # Initialize a FARMReader with the selected model
|
379 |
-
# # reader = FARMReader(model_name_or_path=model_name, use_gpu=False)
|
380 |
-
|
381 |
-
# # # Initialize the question generation pipeline
|
382 |
-
# # pipe = ExtractiveQAPipeline(reader, retriever)
|
383 |
-
|
384 |
-
# # # Initialize the QuestionGenerator
|
385 |
-
# # qg = QuestionGenerator()
|
386 |
-
|
387 |
-
# # # Generate multiple-choice questions
|
388 |
-
# # qa_list = qg.generate(
|
389 |
-
# # wiki_text,
|
390 |
-
# # num_questions=num_questions,
|
391 |
-
# # answer_style='multiple_choice')
|
392 |
-
# # print("QA List Structure:")
|
393 |
-
# # # Display the generated questions and answers
|
394 |
-
# # st.header("Generated Questions and Answers:")
|
395 |
-
# # for qa in qa_list:
|
396 |
-
# # opno=0
|
397 |
-
|
398 |
-
# # # Display the question
|
399 |
-
# # st.write(f"Question: {qno+1}{qa['question']}")
|
400 |
-
|
401 |
-
# # # Display the answer options
|
402 |
-
# # if 'answer' in qa:
|
403 |
-
# # for idx, option in enumerate(qa['answer']):
|
404 |
-
# # # Indicate if the option is correct
|
405 |
-
# # correct_marker = "(correct)" if option["correct"] else ""
|
406 |
-
# # st.write(f"Option {idx + 1}: {option['answer']} {correct_marker}")
|
407 |
-
|
408 |
-
# # # Add a separator after each question-answer pair
|
409 |
-
# # st.write("-" * 40)
|
410 |
-
|
411 |
-
# # # Run the Streamlit app
|
412 |
-
# # if __name__ == "__main__":
|
413 |
-
# # main()
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
# # # import streamlit as st
|
419 |
-
# # # import re
|
420 |
-
# # # import pke
|
421 |
-
# # # import contractions
|
422 |
-
# # # import wikipedia
|
423 |
-
# # # import logging
|
424 |
-
# # # from haystack.document_stores import InMemoryDocumentStore
|
425 |
-
# # # from haystack.utils import clean_wiki_text, convert_files_to_docs, fetch_archive_from_http
|
426 |
-
# # # from transformers.pipelines import question_answering
|
427 |
-
# # # from haystack.nodes import TfidfRetriever
|
428 |
-
# # # from haystack.pipelines import ExtractiveQAPipeline
|
429 |
-
# # # from haystack.nodes import FARMReader
|
430 |
-
# # # import torch
|
431 |
-
|
432 |
-
# # # from main import print_qa
|
433 |
-
# # # from main import QuestionGenerator
|
434 |
-
|
435 |
-
# # # def main():
|
436 |
-
# # # # Initialize Streamlit app
|
437 |
-
# # # st.title("Question Generation using Haystack and Streamlit")
|
438 |
-
|
439 |
-
# # # # Allow user to input text paragraph
|
440 |
-
# # # wiki_text = st.text_area("Input paragraph:", height=200)
|
441 |
-
|
442 |
-
# # # # Allow user to specify the number of questions to generate
|
443 |
-
# # # num_questions = st.slider("Number of questions to generate:", min_value=1, max_value=20, value=5)
|
444 |
-
|
445 |
-
# # # # Allow user to specify the model to use
|
446 |
-
# # # model_options = ["deepset/roberta-base-squad2", "deepset/roberta-base-squad2-distilled", "bert-large-uncased-whole-word-masking-squad2"]
|
447 |
-
# # # model_name = st.selectbox("Select model:", model_options)
|
448 |
-
|
449 |
-
# # # # Button to generate questions
|
450 |
-
# # # if st.button("Generate Questions"):
|
451 |
-
# # # # Initialize the document store
|
452 |
-
# # # document_store = InMemoryDocumentStore()
|
453 |
-
|
454 |
-
# # # # Convert the input text paragraph into a document
|
455 |
-
# # # document = {"content": wiki_text}
|
456 |
-
# # # document_store.write_documents([document])
|
457 |
-
|
458 |
-
# # # # Initialize a TfidfRetriever
|
459 |
-
# # # retriever = TfidfRetriever(document_store=document_store)
|
460 |
-
|
461 |
-
# # # # Initialize a FARMReader with the selected model
|
462 |
-
# # # reader = FARMReader(model_name_or_path=model_name, use_gpu=False)
|
463 |
-
|
464 |
-
# # # # Initialize the question generation pipeline
|
465 |
-
# # # pipe = ExtractiveQAPipeline(reader, retriever)
|
466 |
-
|
467 |
-
# # # # Initialize the QuestionGenerator
|
468 |
-
# # # qg = QuestionGenerator()
|
469 |
-
|
470 |
-
# # # # Generate multiple-choice questions
|
471 |
-
# # # qa_list = qg.generate(
|
472 |
-
# # # wiki_text,
|
473 |
-
# # # num_questions=num_questions,
|
474 |
-
# # # answer_style='multiple_choice')
|
475 |
-
# # # print("QA List Structure:")
|
476 |
-
# # # # Display the generated questions and answers
|
477 |
-
# # # st.header("Generated Questions and Answers:")
|
478 |
-
# # # for qa in qa_list:
|
479 |
-
# # # # Display the question
|
480 |
-
# # # st.write(f"Question: {qa['question']}")
|
481 |
-
|
482 |
-
# # # # Display the answer options
|
483 |
-
# # # if 'answer' in qa:
|
484 |
-
# # # for idx, option in enumerate(qa['answer']):
|
485 |
-
# # # # Indicate if the option is correct
|
486 |
-
# # # correct_marker = "(correct)" if option["correct"] else ""
|
487 |
-
# # # st.write(f"Option {idx + 1}: {option['answer']} {correct_marker}")
|
488 |
-
|
489 |
-
# # # # Add a separator after each question-answer pair
|
490 |
-
# # # st.write("-" * 40)
|
491 |
-
# # # # for qa in qa_list:
|
492 |
-
# # # # print(qa)
|
493 |
-
|
494 |
-
# # # # # Proceed with displaying the generated questions
|
495 |
-
# # # # st.header("Generated Questions:")
|
496 |
-
# # # # for qa in qa_list:
|
497 |
-
# # # # st.write(f"Question: {qa['question']}")
|
498 |
-
# # # # # Adjust the code to match the structure of the output
|
499 |
-
# # # # if 'answers' in qa:
|
500 |
-
# # # # for idx, answer in enumerate(qa['answers']):
|
501 |
-
# # # # prefix = f"Option {idx + 1}:"
|
502 |
-
# # # # if answer["correct"]:
|
503 |
-
# # # # prefix += " (correct)"
|
504 |
-
# # # # st.write(f"{prefix} {answer['text']}")
|
505 |
-
# # # # else:
|
506 |
-
# # # # st.write("No answers available for this question.")
|
507 |
-
# # # # st.write("") # Add an empty line between each question for better readability
|
508 |
-
|
509 |
-
# # # # Run the Streamlit app
|
510 |
-
# # # if __name__ == "__main__":
|
511 |
-
# # # main()
|
|
|
97 |
if __name__ == "__main__":
|
98 |
main()
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|