diff --git a/.gitattributes b/.gitattributes index 81be60eef1cd99cfb80519ca7ef9f0ae0b611dc3..a6344aac8c09253b3b630fb776ae94478aa0275b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,5 +33,3 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text *tfevents* filter=lfs diff=lfs merge=lfs -text -*.pptx filter=lfs diff=lfs merge=lfs -text -pptx_templates/Minimalist_sales_pitch.pptx filter=lfs diff=lfs merge=lfs -text diff --git a/.streamlit/config.toml b/.streamlit/config.toml deleted file mode 100644 index 186939ebda28cf28f9376004a9bf2cade6fc595b..0000000000000000000000000000000000000000 --- a/.streamlit/config.toml +++ /dev/null @@ -1,10 +0,0 @@ -[server] -runOnSave = true -headless = false -maxUploadSize = 0 - -[browser] -gatherUsageStats = false - -[theme] -base = "dark" diff --git a/README.md b/README.md index eb43876a5a31a1a7e8bd3af34a1e5281b95b2c78..b0ef5923c1ca018fcc97f15112f1b03ee6516e38 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ emoji: 🏢 colorFrom: yellow colorTo: green sdk: streamlit -sdk_version: 1.32.2 +sdk_version: 1.26.0 app_file: app.py pinned: false license: mit @@ -16,62 +16,36 @@ We spend a lot of time on creating the slides and organizing our thoughts for an With SlideDeck AI, co-create slide decks on any topic with Generative Artificial Intelligence. Describe your topic and let SlideDeck AI generate a PowerPoint slide deck for you—it's as simple as that! -SlideDeck AI is powered by [Mistral-Nemo-Instruct-2407](https://huggingface.co./mistralai/Mistral-Nemo-Instruct-2407). +SlideDeck AI is powered by [Mistral 7B Instruct](https://huggingface.co./mistralai/Mistral-7B-Instruct-v0.1). Originally, it was built using the Llama 2 API provided by Clarifai. -*Update (v4.0)*: Legacy SlideDeck AI allowed one-shot generation of a slide deck based on the inputs. -In contrast, SlideDeck AI *Reloaded* enables an iterative workflow with a conversational interface, -where you can create and improve the presentation. - - # Process SlideDeck AI works in the following way: -1. Given a topic description, it uses Mistral Nemo Instruct to generate the *initial* content of the slides. +1. Given a topic description, it uses Mistral 7B Instruct to generate the outline/contents of the slides. The output is generated as structured JSON data based on a pre-defined schema. -2. Next, it uses the keywords from the JSON output to search and download a few images with a certain probability. -3. Subsequently, it uses the `python-pptx` library to generate the slides, +2. Subsequently, it uses the `python-pptx` library to generate the slides, based on the JSON data from the previous step. -A user can choose from a set of three pre-defined presentation templates. -4. At this stage onward, a user can provide additional instructions to *refine* the content. -For example, one can ask to add another slide or modify an existing slide. -A history of instructions is maintained. -5. Every time SlideDeck AI generates a PowerPoint presentation, a download button is provided. -Clicking on the button will download the file. - - -# Icons - -SlideDeck AI uses a subset of icons from [bootstrap-icons-1.11.3](https://github.com/twbs/icons) - (MIT license) in the slides. A few icons from [SVG Repo](https://www.svgrepo.com/) -(CC0, MIT, and Apache licenses) are also used. - - -# Known Issues - -- **Connection timeout**: Requests sent to the Hugging Face Inference endpoint might time out. If it still does not work, wait for a while and try again. +Here, a user can choose from a set of three pre-defined presentation templates. +3. In addition, it uses Metaphor to fetch Web pages related to the topic. -The following is not an issue but might appear as a strange behavior: -- **Cannot paste text in the input box**: If the length of the copied text is greater than the maximum -number of allowed characters in the textbox, pasting would not work. +4. ~~Finally, it uses Stable Diffusion 2 to generate an image, based on the title and each slide heading.~~ # Local Development -SlideDeck AI uses [Mistral-Nemo-Instruct-2407](https://huggingface.co./mistralai/Mistral-Nemo-Instruct-2407) +SlideDeck AI uses [Mistral 7B Instruct](https://huggingface.co./mistralai/Mistral-7B-Instruct-v0.1) via the Hugging Face Inference API. -To run this project by yourself, you need to provide the `HUGGINGFACEHUB_API_TOKEN` API key, -for example, in a `.env` file. For image search, the `PEXEL_API_KEY` should be added. -Visit the respective websites to obtain the keys. +To run this project by yourself, you need to provide the `HUGGINGFACEHUB_API_TOKEN` and `METAPHOR_API_KEY` API keys, +for example, in a `.env` file. Visit the respective websites to obtain the keys. # Live Demo -- [SlideDeck AI](https://huggingface.co./spaces/barunsaha/slide-deck-ai) on Hugging Face Spaces -- [Demo video](https://youtu.be/QvAKzNKtk9k) of the chat interface on YouTube +[SlideDeck AI](https://huggingface.co./spaces/barunsaha/slide-deck-ai) # Award -SlideDeck AI has won the 3rd Place in the [Llama 2 Hackathon with Clarifai](https://lablab.ai/event/llama-2-hackathon-with-clarifai) in 2023. \ No newline at end of file +SlideDeck AI has won the 3rd Place in the [Llama 2 Hackathon with Clarifai](https://lablab.ai/event/llama-2-hackathon-with-clarifai). \ No newline at end of file diff --git a/app.py b/app.py index 3206b01226614e50b360b3820db1e124f5bd7064..3d96c9c5cfeac1420519fea66bfac207b53a78fb 100644 --- a/app.py +++ b/app.py @@ -1,415 +1,310 @@ -""" -Streamlit app containing the UI and the application logic. -""" -import datetime -import logging import pathlib -import random -import sys +import logging import tempfile -from typing import List, Union +from typing import List, Tuple -import huggingface_hub import json5 -import requests +import metaphor_python as metaphor import streamlit as st -from langchain_community.chat_message_histories import StreamlitChatMessageHistory -from langchain_core.messages import HumanMessage -from langchain_core.prompts import ChatPromptTemplate - -sys.path.append('..') -sys.path.append('../..') -import helpers.icons_embeddings as ice +import llm_helper +import pptx_helper from global_config import GlobalConfig -from helpers import llm_helper, pptx_helper, text_helper -@st.cache_data -def _load_strings() -> dict: - """ - Load various strings to be displayed in the app. - :return: The dictionary of strings. - """ +APP_TEXT = json5.loads(open(GlobalConfig.APP_STRINGS_FILE, 'r', encoding='utf-8').read()) +GB_CONVERTER = 2 ** 30 + - with open(GlobalConfig.APP_STRINGS_FILE, 'r', encoding='utf-8') as in_file: - return json5.loads(in_file.read()) +logging.basicConfig( + level=GlobalConfig.LOG_LEVEL, + format='%(asctime)s - %(message)s', +) @st.cache_data -def _get_prompt_template(is_refinement: bool) -> str: +def get_contents_wrapper(text: str) -> str: """ - Return a prompt template. + Fetch and cache the slide deck contents on a topic by calling an external API. - :param is_refinement: Whether this is the initial or refinement prompt. - :return: The prompt template as f-string. + :param text: The presentation topic + :return: The slide deck contents or outline in JSON format """ - if is_refinement: - with open(GlobalConfig.REFINEMENT_PROMPT_TEMPLATE, 'r', encoding='utf-8') as in_file: - template = in_file.read() - else: - with open(GlobalConfig.INITIAL_PROMPT_TEMPLATE, 'r', encoding='utf-8') as in_file: - template = in_file.read() - - return template + logging.info('LLM call because of cache miss...') + return llm_helper.generate_slides_content(text).strip() @st.cache_resource -def _get_llm(): +def get_metaphor_client_wrapper() -> metaphor.Metaphor: """ - Get an LLM instance. + Create a Metaphor client for semantic Web search. - :return: The LLM. + :return: Metaphor instance """ - return llm_helper.get_hf_endpoint() + return metaphor.Metaphor(api_key=GlobalConfig.METAPHOR_API_KEY) @st.cache_data -def _get_icons_list() -> List[str]: +def get_web_search_results_wrapper(text: str) -> List[Tuple[str, str]]: """ - Get a list of available icons names without the dir name and file extension. + Fetch and cache the Web search results on a given topic. - :return: A llist of the icons. + :param text: The topic + :return: A list of (title, link) tuples """ - return ice.get_icons_list() - - -APP_TEXT = _load_strings() - -# Session variables -CHAT_MESSAGES = 'chat_messages' -DOWNLOAD_FILE_KEY = 'download_file_name' -IS_IT_REFINEMENT = 'is_it_refinement' - - -logger = logging.getLogger(__name__) + results = [] + search_results = get_metaphor_client_wrapper().search( + text, + use_autoprompt=True, + num_results=5 + ) -texts = list(GlobalConfig.PPTX_TEMPLATE_FILES.keys()) -captions = [GlobalConfig.PPTX_TEMPLATE_FILES[x]['caption'] for x in texts] -pptx_template = st.sidebar.radio( - 'Select a presentation template:', - texts, - captions=captions, - horizontal=True -) + for a_result in search_results.results: + results.append((a_result.title, a_result.url)) + + return results + + +# def get_disk_used_percentage() -> float: +# """ +# Compute the disk usage. +# +# :return: Percentage of the disk space currently used +# """ +# +# total, used, free = shutil.disk_usage(__file__) +# total = total // GB_CONVERTER +# used = used // GB_CONVERTER +# free = free // GB_CONVERTER +# used_perc = 100.0 * used / total +# +# logging.debug(f'Total: {total} GB\n' +# f'Used: {used} GB\n' +# f'Free: {free} GB') +# +# logging.debug('\n'.join(os.listdir())) +# +# return used_perc def build_ui(): """ - Display the input elements for content generation. + Display the input elements for content generation. Only covers the first step. """ + # get_disk_used_percentage() + st.title(APP_TEXT['app_name']) st.subheader(APP_TEXT['caption']) st.markdown( - '![Visitors](https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2Fbarunsaha%2Fslide-deck-ai&countColor=%23263759)' # noqa: E501 + 'Powered by' + ' [Mistral-7B-Instruct-v0.2](https://huggingface.co./mistralai/Mistral-7B-Instruct-v0.2).' + ) + st.markdown( + '*If the JSON is generated or parsed incorrectly, try again later by making minor changes' + ' to the input text.*' ) - with st.expander('Usage Policies and Limitations'): - st.text(APP_TEXT['tos'] + '\n\n' + APP_TEXT['tos2']) - - set_up_chat_ui() - - -def set_up_chat_ui(): - """ - Prepare the chat interface and related functionality. - """ - - with st.expander('Usage Instructions'): - st.markdown(GlobalConfig.CHAT_USAGE_INSTRUCTIONS) - st.markdown( - '[SlideDeck AI](https://github.com/barun-saha/slide-deck-ai) is an Open-Source project.' # noqa: E501 - ' It is is powered by' # noqa: E501 - ' [Mistral-Nemo-Instruct-2407](https://huggingface.co./mistralai/Mistral-Nemo-Instruct-2407).' # noqa: E501 + with st.form('my_form'): + # Topic input + try: + with open(GlobalConfig.PRELOAD_DATA_FILE, 'r', encoding='utf-8') as in_file: + preload_data = json5.loads(in_file.read()) + except (FileExistsError, FileNotFoundError): + preload_data = {'topic': '', 'audience': ''} + + topic = st.text_area( + APP_TEXT['input_labels'][0], + value=preload_data['topic'] ) - st.info( - 'If you like SlideDeck AI, please consider leaving a heart ❤️ on the' - ' [Hugging Face Space](https://huggingface.co./spaces/barunsaha/slide-deck-ai/) or' - ' a star ⭐ on [GitHub](https://github.com/barun-saha/slide-deck-ai).' - ' Your [feedback](https://forms.gle/JECFBGhjvSj7moBx9) is appreciated.' - ) - - # view_messages = st.expander('View the messages in the session state') + texts = list(GlobalConfig.PPTX_TEMPLATE_FILES.keys()) + captions = [GlobalConfig.PPTX_TEMPLATE_FILES[x]['caption'] for x in texts] - st.chat_message('ai').write( - random.choice(APP_TEXT['ai_greetings']) - ) + pptx_template = st.radio( + 'Select a presentation template:', + texts, + captions=captions, + horizontal=True + ) - history = StreamlitChatMessageHistory(key=CHAT_MESSAGES) + st.divider() + submit = st.form_submit_button('Generate slide deck') - if _is_it_refinement(): - template = _get_prompt_template(is_refinement=True) - else: - template = _get_prompt_template(is_refinement=False) - - prompt_template = ChatPromptTemplate.from_template(template) - - # Since Streamlit app reloads at every interaction, display the chat history - # from the save session state - for msg in history.messages: - msg_type = msg.type - if msg_type == 'user': - st.chat_message(msg_type).write(msg.content) - else: - st.chat_message(msg_type).code(msg.content, language='json') - - if prompt := st.chat_input( - placeholder=APP_TEXT['chat_placeholder'], - max_chars=GlobalConfig.LLM_MODEL_MAX_INPUT_LENGTH - ): - if not text_helper.is_valid_prompt(prompt): - st.error( - 'Not enough information provided!' - ' Please be a little more descriptive and type a few words' - ' with a few characters :)' - ) - return - - logger.info('User input: %s | #characters: %d', prompt, len(prompt)) - st.chat_message('user').write(prompt) - - user_messages = _get_user_messages() - user_messages.append(prompt) - list_of_msgs = [ - f'{idx + 1}. {msg}' for idx, msg in enumerate(user_messages) - ] - list_of_msgs = '\n'.join(list_of_msgs) - - if _is_it_refinement(): - formatted_template = prompt_template.format( - **{ - 'instructions': list_of_msgs, - 'previous_content': _get_last_response(), - 'icons_list': '\n'.join(_get_icons_list()) - } - ) - else: - formatted_template = prompt_template.format( - **{ - 'question': prompt, - 'icons_list': '\n'.join(_get_icons_list()) - } - ) - - progress_bar = st.progress(0, 'Preparing to call LLM...') - response = '' + if submit: + # st.write(f'Clicked {time.time()}') + st.session_state.submitted = True - try: - for chunk in _get_llm().stream(formatted_template): - response += chunk + # https://github.com/streamlit/streamlit/issues/3832#issuecomment-1138994421 + if 'submitted' in st.session_state: + progress_text = 'Generating the slides...give it a moment' + progress_bar = st.progress(0, text=progress_text) - # Update the progress bar - progress_percentage = min( - len(response) / GlobalConfig.LLM_MODEL_MAX_OUTPUT_LENGTH, 0.95 - ) - progress_bar.progress( - progress_percentage, - text='Streaming content...this might take a while...' - ) - except requests.exceptions.ConnectionError: - msg = ( - 'A connection error occurred while streaming content from the LLM endpoint.' - ' Unfortunately, the slide deck cannot be generated. Please try again later.' - ) - logger.error(msg) - st.error(msg) - return - except huggingface_hub.errors.ValidationError as ve: - msg = ( - f'An error occurred while trying to generate the content: {ve}' - '\nPlease try again with a significantly shorter input text.' - ) - logger.error(msg) - st.error(msg) - return - except Exception as ex: - msg = ( - f'An unexpected error occurred while generating the content: {ex}' - '\nPlease try again later, possibly with different inputs.' - ) - logger.error(msg) - st.error(msg) - return - - history.add_user_message(prompt) - history.add_ai_message(response) - - # The content has been generated as JSON - # There maybe trailing ``` at the end of the response -- remove them - # To be careful: ``` may be part of the content as well when code is generated - response_cleaned = text_helper.get_clean_json(response) - - logger.info( - 'Cleaned JSON response:: original length: %d | cleaned length: %d', - len(response), len(response_cleaned) - ) - # logger.debug('Cleaned JSON: %s', response_cleaned) + topic_txt = topic.strip() + generate_presentation(topic_txt, pptx_template, progress_bar) - # Now create the PPT file - progress_bar.progress( - GlobalConfig.LLM_PROGRESS_MAX, - text='Finding photos online and generating the slide deck...' - ) - path = generate_slide_deck(response_cleaned) - progress_bar.progress(1.0, text='Done!') + st.divider() + st.text(APP_TEXT['tos']) + st.text(APP_TEXT['tos2']) - st.chat_message('ai').code(response, language='json') - - if path: - _display_download_button(path) - - logger.info( - '#messages in history / 2: %d', - len(st.session_state[CHAT_MESSAGES]) / 2 - ) + st.markdown( + '![Visitors]' + '(https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2Fbarunsaha%2Fslide-deck-ai&countColor=%23263759)' + ) -def generate_slide_deck(json_str: str) -> Union[pathlib.Path, None]: +def generate_presentation(topic: str, pptx_template: str, progress_bar): """ - Create a slide deck and return the file path. In case there is any error creating the slide - deck, the path may be to an empty file. + Process the inputs to generate the slides. - :param json_str: The content in *valid* JSON format. - :return: The path to the .pptx file or `None` in case of error. + :param topic: The presentation topic based on which contents are to be generated + :param pptx_template: The PowerPoint template name to be used + :param progress_bar: Progress bar from the page + :return: """ - try: - parsed_data = json5.loads(json_str) - except ValueError: - st.error( - 'Encountered error while parsing JSON...will fix it and retry' - ) - logger.error( - 'Caught ValueError: trying again after repairing JSON...' - ) - try: - parsed_data = json5.loads(text_helper.fix_malformed_json(json_str)) - except ValueError: - st.error( - 'Encountered an error again while fixing JSON...' - 'the slide deck cannot be created, unfortunately ☹' - '\nPlease try again later.' - ) - logger.error( - 'Caught ValueError: failed to repair JSON!' - ) - - return None - except RecursionError: - st.error( - 'Encountered an error while parsing JSON...' - 'the slide deck cannot be created, unfortunately ☹' - '\nPlease try again later.' - ) - logger.error('Caught RecursionError while parsing JSON. Cannot generate the slide deck!') + topic_length = len(topic) + logging.debug('Input length:: topic: %s', topic_length) - return None - except Exception: - st.error( - 'Encountered an error while parsing JSON...' - 'the slide deck cannot be created, unfortunately ☹' - '\nPlease try again later.' - ) - logger.error( - 'Caught ValueError: failed to parse JSON!' - ) + if topic_length >= 10: + logging.debug('Topic: %s', topic) + target_length = min(topic_length, GlobalConfig.LLM_MODEL_MAX_INPUT_LENGTH) - return None + try: + # Step 1: Generate the contents in JSON format using an LLM + json_str = process_slides_contents(topic[:target_length], progress_bar) + logging.debug('Truncated topic: %s', topic[:target_length]) + logging.debug('Length of JSON: %d', len(json_str)) + + # Step 2: Generate the slide deck based on the template specified + if len(json_str) > 0: + st.info( + 'Tip: The generated content doesn\'t look so great?' + ' Need alternatives? Just change your description text and try again.', + icon="💡️" + ) + else: + st.error( + 'Unfortunately, JSON generation failed, so the next steps would lead' + ' to nowhere. Try again or come back later.' + ) + return - if DOWNLOAD_FILE_KEY in st.session_state: - path = pathlib.Path(st.session_state[DOWNLOAD_FILE_KEY]) - else: - temp = tempfile.NamedTemporaryFile(delete=False, suffix='.pptx') - path = pathlib.Path(temp.name) - st.session_state[DOWNLOAD_FILE_KEY] = str(path) + all_headers = generate_slide_deck(json_str, pptx_template, progress_bar) - if temp: - temp.close() + # Step 3: Bonus stuff: Web references and AI art + show_bonus_stuff(all_headers) - try: - logger.debug('Creating PPTX file: %s...', st.session_state[DOWNLOAD_FILE_KEY]) - pptx_helper.generate_powerpoint_presentation( - parsed_data, - slides_template=pptx_template, - output_file_path=path - ) - except Exception as ex: - st.error(APP_TEXT['content_generation_error']) - logger.error('Caught a generic exception: %s', str(ex)) + except ValueError as ve: + st.error(f'Unfortunately, an error occurred: {ve}! ' + f'Please change the text, try again later, or report it, sharing your inputs.') - return path + else: + st.error('Not enough information provided! Please be little more descriptive :)') -def _is_it_refinement() -> bool: +def process_slides_contents(text: str, progress_bar: st.progress) -> str: """ - Whether it is the initial prompt or a refinement. + Convert given text into structured data and display. Update the UI. - :return: True if it is the initial prompt; False otherwise. + :param text: The topic description for the presentation + :param progress_bar: Progress bar for this step + :return: The contents as a JSON-formatted string """ - if IS_IT_REFINEMENT in st.session_state: - return True - - if len(st.session_state[CHAT_MESSAGES]) >= 2: - # Prepare for the next call - st.session_state[IS_IT_REFINEMENT] = True - return True - - return False + json_str = '' + try: + logging.info('Calling LLM for content generation on the topic: %s', text) + json_str = get_contents_wrapper(text) + except Exception as ex: + st.error( + f'An exception occurred while trying to convert to JSON. It could be because of heavy' + f' traffic or something else. Try doing it again or try again later.' + f'\nError message: {ex}' + ) -def _get_user_messages() -> List[str]: - """ - Get a list of user messages submitted until now from the session state. + progress_bar.progress(50, text='Contents generated') - :return: The list of user messages. - """ + with st.expander('The generated contents (in JSON format)'): + st.code(json_str, language='json') - return [ - msg.content for msg in st.session_state[CHAT_MESSAGES] if isinstance(msg, HumanMessage) - ] + return json_str -def _get_last_response() -> str: +def generate_slide_deck(json_str: str, pptx_template: str, progress_bar) -> List: """ - Get the last response generated by AI. + Create a slide deck. - :return: The response text. + :param json_str: The contents in JSON format + :param pptx_template: The PPTX template name + :param progress_bar: Progress bar + :return: A list of all slide headers and the title """ - return st.session_state[CHAT_MESSAGES][-1].content + progress_text = 'Creating the slide deck...give it a moment' + progress_bar.progress(75, text=progress_text) + # # Get a unique name for the file to save -- use the session ID + # ctx = st_sr.get_script_run_ctx() + # session_id = ctx.session_id + # timestamp = time.time() + # output_file_name = f'{session_id}_{timestamp}.pptx' -def _display_messages_history(view_messages: st.expander): - """ - Display the history of messages. + temp = tempfile.NamedTemporaryFile(delete=False, suffix='.pptx') + path = pathlib.Path(temp.name) - :param view_messages: The list of AI and Human messages. - """ + logging.info('Creating PPTX file...') + all_headers = pptx_helper.generate_powerpoint_presentation( + json_str, + as_yaml=False, + slides_template=pptx_template, + output_file_path=path + ) + progress_bar.progress(100, text='Done!') - with view_messages: - view_messages.json(st.session_state[CHAT_MESSAGES]) + with open(path, 'rb') as f: + st.download_button('Download PPTX file', f, file_name='Presentation.pptx') + return all_headers -def _display_download_button(file_path: pathlib.Path): + +def show_bonus_stuff(ppt_headers: List[str]): """ - Display a download button to download a slide deck. + Show bonus stuff for the presentation. - :param file_path: The path of the .pptx file. + :param ppt_headers: A list of the slide headings. """ - with open(file_path, 'rb') as download_file: - st.download_button( - 'Download PPTX file ⬇️', - data=download_file, - file_name='Presentation.pptx', - key=datetime.datetime.now() - ) + # Use the presentation title and the slide headers to find relevant info online + logging.info('Calling Metaphor search...') + ppt_text = ' '.join(ppt_headers) + search_results = get_web_search_results_wrapper(ppt_text) + md_text_items = [] + + for (title, link) in search_results: + md_text_items.append(f'[{title}]({link})') + + with st.expander('Related Web references'): + st.markdown('\n\n'.join(md_text_items)) + + logging.info('Done!') + + # # Avoid image generation. It costs time and an API call, so just limit to the text generation. + # with st.expander('AI-generated image on the presentation topic'): + # logging.info('Calling SDXL for image generation...') + # # img_empty.write('') + # # img_text.write(APP_TEXT['image_info']) + # image = get_ai_image_wrapper(ppt_text) + # + # if len(image) > 0: + # image = base64.b64decode(image) + # st.image(image, caption=ppt_text) + # st.info('Tip: Right-click on the image to save it.', icon="💡️") + # logging.info('Image added') def main(): diff --git a/clarifai_grpc_helper.py b/clarifai_grpc_helper.py new file mode 100644 index 0000000000000000000000000000000000000000..ca153657f4124f2ec3eb65839b8b5ae010cafc0e --- /dev/null +++ b/clarifai_grpc_helper.py @@ -0,0 +1,71 @@ +from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel +from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc +from clarifai_grpc.grpc.api.status import status_code_pb2 + +from global_config import GlobalConfig + + +CHANNEL = ClarifaiChannel.get_grpc_channel() +STUB = service_pb2_grpc.V2Stub(CHANNEL) + +METADATA = ( + ('authorization', 'Key ' + GlobalConfig.CLARIFAI_PAT), +) + +USER_DATA_OBJECT = resources_pb2.UserAppIDSet( + user_id=GlobalConfig.CLARIFAI_USER_ID, + app_id=GlobalConfig.CLARIFAI_APP_ID +) + +RAW_TEXT = '''You are a helpful, intelligent chatbot. Create the slides for a presentation on the given topic. Include main headings for each slide, detailed bullet points for each slide. Add relevant content to each slide. Do not output any blank line. + +Topic: +Talk about AI, covering what it is and how it works. Add its pros, cons, and future prospects. Also, cover its job prospects. +''' + + +def get_text_from_llm(prompt: str) -> str: + post_model_outputs_response = STUB.PostModelOutputs( + service_pb2.PostModelOutputsRequest( + user_app_id=USER_DATA_OBJECT, # The userDataObject is created in the overview and is required when using a PAT + model_id=GlobalConfig.CLARIFAI_MODEL_ID, + # version_id=MODEL_VERSION_ID, # This is optional. Defaults to the latest model version + inputs=[ + resources_pb2.Input( + data=resources_pb2.Data( + text=resources_pb2.Text( + raw=prompt + ) + ) + ) + ] + ), + metadata=METADATA + ) + + if post_model_outputs_response.status.code != status_code_pb2.SUCCESS: + print(post_model_outputs_response.status) + raise Exception(f"Post model outputs failed, status: {post_model_outputs_response.status.description}") + + # Since we have one input, one output will exist here + output = post_model_outputs_response.outputs[0] + + # print("Completion:\n") + # print(output.data.text.raw) + + return output.data.text.raw + + +if __name__ == '__main__': + topic = ('Talk about AI, covering what it is and how it works.' + ' Add its pros, cons, and future prospects.' + ' Also, cover its job prospects.' + ) + print(topic) + + with open(GlobalConfig.SLIDES_TEMPLATE_FILE, 'r') as in_file: + prompt_txt = in_file.read() + prompt_txt = prompt_txt.replace('{topic}', topic) + response_txt = get_text_from_llm(prompt_txt) + + print('Output:\n', response_txt) diff --git a/examples/example_04.json b/examples/example_04.json deleted file mode 100644 index f8d948e7acf4a8a538800c1437cf9b190215132d..0000000000000000000000000000000000000000 --- a/examples/example_04.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "topic": "12 slides on a basic tutorial on Python along with examples" -} \ No newline at end of file diff --git a/file_embeddings/embeddings.npy b/file_embeddings/embeddings.npy deleted file mode 100644 index 9e2dda13f1c5758bd0f9fdab9a9fc5ae9fc11de2..0000000000000000000000000000000000000000 --- a/file_embeddings/embeddings.npy +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:64a1ba79b20c81ba7ed6604468736f74ae89813fe378191af1d8574c008b3ab5 -size 326784 diff --git a/file_embeddings/icons.npy b/file_embeddings/icons.npy deleted file mode 100644 index 569312d358b126c1fec543275163a78466767d37..0000000000000000000000000000000000000000 --- a/file_embeddings/icons.npy +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce5ce4c86bb213915606921084b3516464154edcae12f4bc708d62c6bd7acebb -size 51168 diff --git a/global_config.py b/global_config.py index b983309874f8c653ef70175442130851fb9e0d59..05e6b40402cb2cc6a07fe7b4f3f0c6f520b61c3d 100644 --- a/global_config.py +++ b/global_config.py @@ -1,7 +1,3 @@ -""" -A set of configurations used by the app. -""" -import logging import os from dataclasses import dataclass @@ -13,72 +9,32 @@ load_dotenv() @dataclass(frozen=True) class GlobalConfig: - """ - A data class holding the configurations. - """ - - HF_LLM_MODEL_NAME = 'mistralai/Mistral-Nemo-Instruct-2407' - LLM_MODEL_TEMPERATURE = 0.2 - LLM_MODEL_MIN_OUTPUT_LENGTH = 100 - LLM_MODEL_MAX_OUTPUT_LENGTH = 4 * 4096 # tokens - LLM_MODEL_MAX_INPUT_LENGTH = 400 # characters + HF_LLM_MODEL_NAME = 'mistralai/Mistral-7B-Instruct-v0.2' + LLM_MODEL_TEMPERATURE: float = 0.2 + LLM_MODEL_MIN_OUTPUT_LENGTH: int = 50 + LLM_MODEL_MAX_OUTPUT_LENGTH: int = 2000 + LLM_MODEL_MAX_INPUT_LENGTH: int = 300 HUGGINGFACEHUB_API_TOKEN = os.environ.get('HUGGINGFACEHUB_API_TOKEN', '') + METAPHOR_API_KEY = os.environ.get('METAPHOR_API_KEY', '') LOG_LEVEL = 'DEBUG' - COUNT_TOKENS = False APP_STRINGS_FILE = 'strings.json' PRELOAD_DATA_FILE = 'examples/example_02.json' SLIDES_TEMPLATE_FILE = 'langchain_templates/template_combined.txt' - INITIAL_PROMPT_TEMPLATE = 'langchain_templates/chat_prompts/initial_template_v4_two_cols_img.txt' - REFINEMENT_PROMPT_TEMPLATE = 'langchain_templates/chat_prompts/refinement_template_v4_two_cols_img.txt' - - LLM_PROGRESS_MAX = 90 - ICONS_DIR = 'icons/png128/' - TINY_BERT_MODEL = 'gaunernst/bert-mini-uncased' - EMBEDDINGS_FILE_NAME = 'file_embeddings/embeddings.npy' - ICONS_FILE_NAME = 'file_embeddings/icons.npy' + JSON_TEMPLATE_FILE = 'langchain_templates/text_to_json_template_02.txt' PPTX_TEMPLATE_FILES = { - 'Basic': { + 'Blank': { 'file': 'pptx_templates/Blank.pptx', - 'caption': 'A good start (Uses [photos](https://unsplash.com/photos/AFZ-qBPEceA) by [cetteup](https://unsplash.com/@cetteup?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash) on [Unsplash](https://unsplash.com/photos/a-foggy-forest-filled-with-lots-of-trees-d3ci37Gcgxg?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash)) 🟧' - }, - 'Minimalist Sales Pitch': { - 'file': 'pptx_templates/Minimalist_sales_pitch.pptx', - 'caption': 'In high contrast ⬛' + 'caption': 'A good start' }, 'Ion Boardroom': { 'file': 'pptx_templates/Ion_Boardroom.pptx', - 'caption': 'Make some bold decisions 🟥' + 'caption': 'Make some bold decisions' }, 'Urban Monochrome': { 'file': 'pptx_templates/Urban_monochrome.pptx', - 'caption': 'Marvel in a monochrome dream ⬜' - }, + 'caption': 'Marvel in a monochrome dream' + } } - - # This is a long text, so not incorporated as a string in `strings.json` - CHAT_USAGE_INSTRUCTIONS = ( - 'Briefly describe your topic of presentation in the textbox provided below.' - ' For example:\n' - '- Make a slide deck on AI.' - '\n\n' - 'Subsequently, you can add follow-up instructions, e.g.:\n' - '- Can you add a slide on GPUs?' - '\n\n' - ' You can also ask it to refine any particular slide, e.g.:\n' - '- Make the slide with title \'Examples of AI\' a bit more descriptive.' - '\n\n' - 'See this [demo video](https://youtu.be/QvAKzNKtk9k) for a brief walkthrough.\n\n' - ' SlideDeck AI does not have access to the Web, apart for searching for images relevant' - ' to the slides. Photos are added probabilistically; transparency needs to be changed' - ' manually, if required.' - ) - - -logging.basicConfig( - level=GlobalConfig.LOG_LEVEL, - format='%(asctime)s - %(levelname)s - %(name)s - %(message)s', - datefmt='%Y-%m-%d %H:%M:%S' -) diff --git a/helpers/__init__.py b/helpers/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/helpers/icons_embeddings.py b/helpers/icons_embeddings.py deleted file mode 100644 index 048a921ba99056dfd1f84e3651c3b20203359547..0000000000000000000000000000000000000000 --- a/helpers/icons_embeddings.py +++ /dev/null @@ -1,166 +0,0 @@ -""" -Generate and save the embeddings of a pre-defined list of icons. -Compare them with keywords embeddings to find most relevant icons. -""" -import os -import pathlib -import sys -from typing import List, Tuple - -import numpy as np -from sklearn.metrics.pairwise import cosine_similarity -from transformers import BertTokenizer, BertModel - -sys.path.append('..') -sys.path.append('../..') - -from global_config import GlobalConfig - - -tokenizer = BertTokenizer.from_pretrained(GlobalConfig.TINY_BERT_MODEL) -model = BertModel.from_pretrained(GlobalConfig.TINY_BERT_MODEL) - - -def get_icons_list() -> List[str]: - """ - Get a list of available icons. - - :return: The icons file names. - """ - - items = pathlib.Path('../' + GlobalConfig.ICONS_DIR).glob('*.png') - items = [ - os.path.basename(str(item)).removesuffix('.png') for item in items - ] - - return items - - -def get_embeddings(texts) -> np.ndarray: - """ - Generate embeddings for a list of texts using a pre-trained language model. - - :param texts: A string or a list of strings to be converted into embeddings. - :type texts: Union[str, List[str]] - :return: A NumPy array containing the embeddings for the input texts. - :rtype: numpy.ndarray - - :raises ValueError: If the input is not a string or a list of strings, or if any element - in the list is not a string. - - Example usage: - >>> keyword = 'neural network' - >>> file_names = ['neural_network_icon.png', 'data_analysis_icon.png', 'machine_learning.png'] - >>> keyword_embeddings = get_embeddings(keyword) - >>> file_name_embeddings = get_embeddings(file_names) - """ - - inputs = tokenizer(texts, return_tensors='pt', padding=True, max_length=128, truncation=True) - outputs = model(**inputs) - - return outputs.last_hidden_state.mean(dim=1).detach().numpy() - - -def save_icons_embeddings(): - """ - Generate and save the embeddings for the icon file names. - """ - - file_names = get_icons_list() - print(f'{len(file_names)} icon files available...') - file_name_embeddings = get_embeddings(file_names) - print(f'file_name_embeddings.shape: {file_name_embeddings.shape}') - - # Save embeddings to a file - np.save(GlobalConfig.EMBEDDINGS_FILE_NAME, file_name_embeddings) - np.save(GlobalConfig.ICONS_FILE_NAME, file_names) # Save file names for reference - - -def load_saved_embeddings() -> Tuple[np.ndarray, np.ndarray]: - """ - Load precomputed embeddings and icons file names. - - :return: The embeddings and the icon file names. - """ - - file_name_embeddings = np.load(GlobalConfig.EMBEDDINGS_FILE_NAME) - file_names = np.load(GlobalConfig.ICONS_FILE_NAME) - - return file_name_embeddings, file_names - - -def find_icons(keywords: List[str]) -> List[str]: - """ - Find relevant icon file names for a list of keywords. - - :param keywords: The list of one or more keywords. - :return: A list of the file names relevant for each keyword. - """ - - keyword_embeddings = get_embeddings(keywords) - file_name_embeddings, file_names = load_saved_embeddings() - - # Compute similarity - similarities = cosine_similarity(keyword_embeddings, file_name_embeddings) - icon_files = file_names[np.argmax(similarities, axis=-1)] - - return icon_files - - -def main(): - """ - Example usage. - """ - - # Run this again if icons are to be added/removed - save_icons_embeddings() - - keywords = [ - 'deep learning', - '', - 'recycling', - 'handshake', - 'Ferry', - 'rain drop', - 'speech bubble', - 'mental resilience', - 'turmeric', - 'Art', - 'price tag', - 'Oxygen', - 'oxygen', - 'Social Connection', - 'Accomplishment', - 'Python', - 'XML', - 'Handshake', - ] - icon_files = find_icons(keywords) - print( - f'The relevant icon files are:\n' - f'{list(zip(keywords, icon_files))}' - ) - - # BERT tiny: - # [('deep learning', 'deep-learning'), ('', '123'), ('recycling', 'refinery'), - # ('handshake', 'dash-circle'), ('Ferry', 'cart'), ('rain drop', 'bucket'), - # ('speech bubble', 'globe'), ('mental resilience', 'exclamation-triangle'), - # ('turmeric', 'kebab'), ('Art', 'display'), ('price tag', 'bug-fill'), - # ('Oxygen', 'radioactive')] - - # BERT mini - # [('deep learning', 'deep-learning'), ('', 'compass'), ('recycling', 'tools'), - # ('handshake', 'bandaid'), ('Ferry', 'cart'), ('rain drop', 'trash'), - # ('speech bubble', 'image'), ('mental resilience', 'recycle'), ('turmeric', 'linkedin'), - # ('Art', 'book'), ('price tag', 'card-image'), ('Oxygen', 'radioactive')] - - # BERT small - # [('deep learning', 'deep-learning'), ('', 'gem'), ('recycling', 'tools'), - # ('handshake', 'handbag'), ('Ferry', 'truck'), ('rain drop', 'bucket'), - # ('speech bubble', 'strategy'), ('mental resilience', 'deep-learning'), - # ('turmeric', 'flower'), - # ('Art', 'book'), ('price tag', 'hotdog'), ('Oxygen', 'radioactive')] - - -if __name__ == '__main__': - main() diff --git a/helpers/image_search.py b/helpers/image_search.py deleted file mode 100644 index 4266ceee4dfc435a634f257ff823129406080316..0000000000000000000000000000000000000000 --- a/helpers/image_search.py +++ /dev/null @@ -1,148 +0,0 @@ -""" -Search photos using Pexels API. -""" -import logging -import os -import random -from io import BytesIO -from typing import Union, Tuple, Literal -from urllib.parse import urlparse, parse_qs - -import requests -from dotenv import load_dotenv - - -load_dotenv() - - -REQUEST_TIMEOUT = 12 -MAX_PHOTOS = 3 - - -# Only show errors -logging.getLogger('urllib3').setLevel(logging.ERROR) -# Disable all child loggers of urllib3, e.g. urllib3.connectionpool -# logging.getLogger('urllib3').propagate = True - - - -def search_pexels( - query: str, - size: Literal['small', 'medium', 'large'] = 'medium', - per_page: int = MAX_PHOTOS -) -> dict: - """ - Searches for images on Pexels using the provided query. - - This function sends a GET request to the Pexels API with the specified search query - and authorization header containing the API key. It returns the JSON response from the API. - - [2024-08-31] Note: - `curl` succeeds but API call via Python `requests` fail. Apparently, this could be due to - Cloudflare (or others) blocking the requests, perhaps identifying as Web-scraping. So, - changing the user-agent to Firefox. - https://stackoverflow.com/a/74674276/147021 - https://stackoverflow.com/a/51268523/147021 - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox#linux - - :param query: The search query for finding images. - :param size: The size of the images: small, medium, or large. - :param per_page: No. of results to be displayed per page. - :return: The JSON response from the Pexels API containing search results. - :raises requests.exceptions.RequestException: If the request to the Pexels API fails. - """ - - url = 'https://api.pexels.com/v1/search' - headers = { - 'Authorization': os.getenv('PEXEL_API_KEY'), - 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0', - } - params = { - 'query': query, - 'size': size, - 'page': 1, - 'per_page': per_page - } - response = requests.get(url, headers=headers, params=params, timeout=REQUEST_TIMEOUT) - response.raise_for_status() # Ensure the request was successful - - return response.json() - - -def get_photo_url_from_api_response( - json_response: dict -) -> Tuple[Union[str, None], Union[str, None]]: - """ - Return a randomly chosen photo from a Pexels search API response. In addition, also return - the original URL of the page on Pexels. - - :param json_response: The JSON response. - :return: The selected photo URL and page URL or `None`. - """ - - page_url = None - photo_url = None - - if 'photos' in json_response: - photos = json_response['photos'] - - if photos: - photo_idx = random.choice(list(range(MAX_PHOTOS))) - photo = photos[photo_idx] - - if 'url' in photo: - page_url = photo['url'] - - if 'src' in photo: - if 'large' in photo['src']: - photo_url = photo['src']['large'] - elif 'original' in photo['src']: - photo_url = photo['src']['original'] - - return photo_url, page_url - - -def get_image_from_url(url: str) -> BytesIO: - """ - Fetches an image from the specified URL and returns it as a BytesIO object. - - This function sends a GET request to the provided URL, retrieves the image data, - and wraps it in a BytesIO object, which can be used like a file. - - :param url: The URL of the image to be fetched. - :return: A BytesIO object containing the image data. - :raises requests.exceptions.RequestException: If the request to the URL fails. - """ - - headers = { - 'Authorization': os.getenv('PEXEL_API_KEY'), - 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0', - } - response = requests.get(url, headers=headers, stream=True, timeout=REQUEST_TIMEOUT) - response.raise_for_status() - image_data = BytesIO(response.content) - - return image_data - - -def extract_dimensions(url: str) -> Tuple[int, int]: - """ - Extracts the height and width from the URL parameters. - - :param url: The URL containing the image dimensions. - :return: A tuple containing the width and height as integers. - """ - parsed_url = urlparse(url) - query_params = parse_qs(parsed_url.query) - width = int(query_params.get('w', [0])[0]) - height = int(query_params.get('h', [0])[0]) - - return width, height - - -if __name__ == '__main__': - print( - search_pexels( - query='people' - ) - ) diff --git a/helpers/pptx_helper.py b/helpers/pptx_helper.py deleted file mode 100644 index 682431542c287ce1f7da676b9a7d98aad73e88cd..0000000000000000000000000000000000000000 --- a/helpers/pptx_helper.py +++ /dev/null @@ -1,982 +0,0 @@ -""" -A set of functions to create a PowerPoint slide deck. -""" -import logging -import os -import pathlib -import random -import re -import sys -import tempfile -from typing import List, Tuple, Optional - -import json5 -import pptx -from dotenv import load_dotenv -from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE -from pptx.shapes.placeholder import PicturePlaceholder, SlidePlaceholder - -sys.path.append('..') -sys.path.append('../..') - -import helpers.icons_embeddings as ice -import helpers.image_search as ims -from global_config import GlobalConfig - - -load_dotenv() - - -# English Metric Unit (used by PowerPoint) to inches -EMU_TO_INCH_SCALING_FACTOR = 1.0 / 914400 -INCHES_3 = pptx.util.Inches(3) -INCHES_2 = pptx.util.Inches(2) -INCHES_1_5 = pptx.util.Inches(1.5) -INCHES_1 = pptx.util.Inches(1) -INCHES_0_8 = pptx.util.Inches(0.8) -INCHES_0_9 = pptx.util.Inches(0.9) -INCHES_0_5 = pptx.util.Inches(0.5) -INCHES_0_4 = pptx.util.Inches(0.4) -INCHES_0_3 = pptx.util.Inches(0.3) -INCHES_0_2 = pptx.util.Inches(0.2) - -STEP_BY_STEP_PROCESS_MARKER = '>> ' -ICON_BEGINNING_MARKER = '[[' -ICON_END_MARKER = ']]' - -ICON_SIZE = INCHES_0_8 -ICON_BG_SIZE = INCHES_1 - -IMAGE_DISPLAY_PROBABILITY = 1 / 3.0 -FOREGROUND_IMAGE_PROBABILITY = 0.8 - -SLIDE_NUMBER_REGEX = re.compile(r"^slide[ ]+\d+:", re.IGNORECASE) -ICONS_REGEX = re.compile(r"\[\[(.*?)\]\]\s*(.*)") - -ICON_COLORS = [ - pptx.dml.color.RGBColor.from_string('800000'), # Maroon - pptx.dml.color.RGBColor.from_string('6A5ACD'), # SlateBlue - pptx.dml.color.RGBColor.from_string('556B2F'), # DarkOliveGreen - pptx.dml.color.RGBColor.from_string('2F4F4F'), # DarkSlateGray - pptx.dml.color.RGBColor.from_string('4682B4'), # SteelBlue - pptx.dml.color.RGBColor.from_string('5F9EA0'), # CadetBlue -] - - -logger = logging.getLogger(__name__) -logging.getLogger('PIL.PngImagePlugin').setLevel(logging.ERROR) - - -def remove_slide_number_from_heading(header: str) -> str: - """ - Remove the slide number from a given slide header. - - :param header: The header of a slide. - :return: The header without slide number. - """ - - if SLIDE_NUMBER_REGEX.match(header): - idx = header.find(':') - header = header[idx + 1:] - - return header - - -def generate_powerpoint_presentation( - parsed_data: dict, - slides_template: str, - output_file_path: pathlib.Path -) -> List: - """ - Create and save a PowerPoint presentation file containing the content in JSON format. - - :param parsed_data: The presentation content as parsed JSON data. - :param slides_template: The PPTX template to use. - :param output_file_path: The path of the PPTX file to save as. - :return: A list of presentation title and slides headers. - """ - - presentation = pptx.Presentation(GlobalConfig.PPTX_TEMPLATE_FILES[slides_template]['file']) - slide_width_inch, slide_height_inch = _get_slide_width_height_inches(presentation) - - # The title slide - title_slide_layout = presentation.slide_layouts[0] - slide = presentation.slides.add_slide(title_slide_layout) - title = slide.shapes.title - subtitle = slide.placeholders[1] - title.text = parsed_data['title'] - logger.info( - 'PPT title: %s | #slides: %d | template: %s', - title.text, len(parsed_data['slides']), - GlobalConfig.PPTX_TEMPLATE_FILES[slides_template]['file'] - ) - subtitle.text = 'by Myself and SlideDeck AI :)' - all_headers = [title.text, ] - - # Add content in a loop - for a_slide in parsed_data['slides']: - is_processing_done = _handle_icons_ideas( - presentation=presentation, - slide_json=a_slide, - slide_width_inch=slide_width_inch, - slide_height_inch=slide_height_inch - ) - - if not is_processing_done: - is_processing_done = _handle_double_col_layout( - presentation=presentation, - slide_json=a_slide, - slide_width_inch=slide_width_inch, - slide_height_inch=slide_height_inch - ) - - if not is_processing_done: - is_processing_done = _handle_step_by_step_process( - presentation=presentation, - slide_json=a_slide, - slide_width_inch=slide_width_inch, - slide_height_inch=slide_height_inch - ) - - if not is_processing_done: - _handle_default_display( - presentation=presentation, - slide_json=a_slide, - slide_width_inch=slide_width_inch, - slide_height_inch=slide_height_inch - ) - - # The thank-you slide - last_slide_layout = presentation.slide_layouts[0] - slide = presentation.slides.add_slide(last_slide_layout) - title = slide.shapes.title - title.text = 'Thank you!' - - presentation.save(output_file_path) - - return all_headers - - -def get_flat_list_of_contents(items: list, level: int) -> List[Tuple]: - """ - Flatten a (hierarchical) list of bullet points to a single list containing each item and - its level. - - :param items: A bullet point (string or list). - :param level: The current level of hierarchy. - :return: A list of (bullet item text, hierarchical level) tuples. - """ - - flat_list = [] - - for item in items: - if isinstance(item, str): - flat_list.append((item, level)) - elif isinstance(item, list): - flat_list = flat_list + get_flat_list_of_contents(item, level + 1) - - return flat_list - - -def get_slide_placeholders( - slide: pptx.slide.Slide, - layout_number: int, - is_debug: bool = False -) -> List[Tuple[int, str]]: - """ - Return the index and name (lower case) of all placeholders present in a slide, except - the title placeholder. - - A placeholder in a slide is a place to add content. Each placeholder has a name and an index. - This index is NOT a list index, rather a set of keys used to look up a dict. So, `idx` is - non-contiguous. Also, the title placeholder of a slide always has index 0. User-added - placeholder get indices assigned starting from 10. - - With user-edited or added placeholders, their index may be difficult to track. This function - returns the placeholders name as well, which could be useful to distinguish between the - different placeholder. - - :param slide: The slide. - :param layout_number: The layout number used by the slide. - :param is_debug: Whether to print debugging statements. - :return: A list containing placeholders (idx, name) tuples, except the title placeholder. - """ - - if is_debug: - print( - f'Slide layout #{layout_number}:' - f' # of placeholders: {len(slide.shapes.placeholders)} (including the title)' - ) - - placeholders = [ - (shape.placeholder_format.idx, shape.name.lower()) for shape in slide.shapes.placeholders - ] - placeholders.pop(0) # Remove the title placeholder - - if is_debug: - print(placeholders) - - return placeholders - - -def _handle_default_display( - presentation: pptx.Presentation, - slide_json: dict, - slide_width_inch: float, - slide_height_inch: float -): - """ - Display a list of text in a slide. - - :param presentation: The presentation object. - :param slide_json: The content of the slide as JSON data. - :param slide_width_inch: The width of the slide in inches. - :param slide_height_inch: The height of the slide in inches. - """ - - status = False - - if 'img_keywords' in slide_json: - if random.random() < IMAGE_DISPLAY_PROBABILITY: - if random.random() < FOREGROUND_IMAGE_PROBABILITY: - status = _handle_display_image__in_foreground( - presentation, - slide_json, - slide_width_inch, - slide_height_inch - ) - else: - status = _handle_display_image__in_background( - presentation, - slide_json, - slide_width_inch, - slide_height_inch - ) - - if status: - return - - # Image display failed, so display only text - bullet_slide_layout = presentation.slide_layouts[1] - slide = presentation.slides.add_slide(bullet_slide_layout) - - shapes = slide.shapes - title_shape = shapes.title - - try: - body_shape = shapes.placeholders[1] - except KeyError: - placeholders = get_slide_placeholders(slide, layout_number=1) - body_shape = shapes.placeholders[placeholders[0][0]] - - title_shape.text = remove_slide_number_from_heading(slide_json['heading']) - text_frame = body_shape.text_frame - - # The bullet_points may contain a nested hierarchy of JSON arrays - # In some scenarios, it may contain objects (dictionaries) because the LLM generated so - # ^ The second scenario is not covered - - flat_items_list = get_flat_list_of_contents(slide_json['bullet_points'], level=0) - - for idx, an_item in enumerate(flat_items_list): - if idx == 0: - text_frame.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - else: - paragraph = text_frame.add_paragraph() - paragraph.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - paragraph.level = an_item[1] - - _handle_key_message( - the_slide=slide, - slide_json=slide_json, - slide_height_inch=slide_height_inch, - slide_width_inch=slide_width_inch - ) - - -def _handle_display_image__in_foreground( - presentation: pptx.Presentation(), - slide_json: dict, - slide_width_inch: float, - slide_height_inch: float -) -> bool: - """ - Create a slide with text and image using a picture placeholder layout. If not image keyword is - available, it will add only text to the slide. - - :param presentation: The presentation object. - :param slide_json: The content of the slide as JSON data. - :param slide_width_inch: The width of the slide in inches. - :param slide_height_inch: The height of the slide in inches. - :return: True if the side has been processed. - """ - - img_keywords = slide_json['img_keywords'].strip() - slide = presentation.slide_layouts[8] # Picture with Caption - slide = presentation.slides.add_slide(slide) - placeholders = None - - title_placeholder = slide.shapes.title - title_placeholder.text = remove_slide_number_from_heading(slide_json['heading']) - - try: - pic_col: PicturePlaceholder = slide.shapes.placeholders[1] - except KeyError: - placeholders = get_slide_placeholders(slide, layout_number=8) - pic_col = None - for idx, name in placeholders: - if 'picture' in name: - pic_col: PicturePlaceholder = slide.shapes.placeholders[idx] - - try: - text_col: SlidePlaceholder = slide.shapes.placeholders[2] - except KeyError: - text_col = None - if not placeholders: - placeholders = get_slide_placeholders(slide, layout_number=8) - - for idx, name in placeholders: - if 'content' in name: - text_col: SlidePlaceholder = slide.shapes.placeholders[idx] - - flat_items_list = get_flat_list_of_contents(slide_json['bullet_points'], level=0) - - for idx, an_item in enumerate(flat_items_list): - if idx == 0: - text_col.text_frame.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - else: - paragraph = text_col.text_frame.add_paragraph() - paragraph.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - paragraph.level = an_item[1] - - if not img_keywords: - # No keywords, so no image search and addition - return True - - try: - photo_url, page_url = ims.get_photo_url_from_api_response( - ims.search_pexels(query=img_keywords, size='medium') - ) - - if photo_url: - pic_col.insert_picture( - ims.get_image_from_url(photo_url) - ) - - _add_text_at_bottom( - slide=slide, - slide_width_inch=slide_width_inch, - slide_height_inch=slide_height_inch, - text='Photo provided by Pexels', - hyperlink=page_url - ) - except Exception as ex: - logger.error( - '*** Error occurred while running adding image to slide: %s', - str(ex) - ) - - return True - - -def _handle_display_image__in_background( - presentation: pptx.Presentation(), - slide_json: dict, - slide_width_inch: float, - slide_height_inch: float -) -> bool: - """ - Add a slide with text and an image in the background. It works just like - `_handle_default_display()` but with a background image added. If not image keyword is - available, it will add only text to the slide. - - :param presentation: The presentation object. - :param slide_json: The content of the slide as JSON data. - :param slide_width_inch: The width of the slide in inches. - :param slide_height_inch: The height of the slide in inches. - :return: True if the slide has been processed. - """ - - img_keywords = slide_json['img_keywords'].strip() - - # Add a photo in the background, text in the foreground - slide = presentation.slides.add_slide(presentation.slide_layouts[1]) - title_shape = slide.shapes.title - - try: - body_shape = slide.shapes.placeholders[1] - except KeyError: - placeholders = get_slide_placeholders(slide, layout_number=1) - # Layout 1 usually has two placeholders, including the title - body_shape = slide.shapes.placeholders[placeholders[0][0]] - - title_shape.text = remove_slide_number_from_heading(slide_json['heading']) - - flat_items_list = get_flat_list_of_contents(slide_json['bullet_points'], level=0) - - for idx, an_item in enumerate(flat_items_list): - if idx == 0: - body_shape.text_frame.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - else: - paragraph = body_shape.text_frame.add_paragraph() - paragraph.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - paragraph.level = an_item[1] - - if not img_keywords: - # No keywords, so no image search and addition - return True - - try: - photo_url, page_url = ims.get_photo_url_from_api_response( - ims.search_pexels(query=img_keywords, size='large') - ) - - if photo_url: - picture = slide.shapes.add_picture( - image_file=ims.get_image_from_url(photo_url), - left=0, - top=0, - width=pptx.util.Inches(slide_width_inch), - ) - - _add_text_at_bottom( - slide=slide, - slide_width_inch=slide_width_inch, - slide_height_inch=slide_height_inch, - text='Photo provided by Pexels', - hyperlink=page_url - ) - - # Move picture to background - # https://github.com/scanny/python-pptx/issues/49#issuecomment-137172836 - slide.shapes._spTree.remove(picture._element) - slide.shapes._spTree.insert(2, picture._element) - except Exception as ex: - logger.error( - '*** Error occurred while running adding image to the slide background: %s', - str(ex) - ) - - return True - - -def _handle_icons_ideas( - presentation: pptx.Presentation(), - slide_json: dict, - slide_width_inch: float, - slide_height_inch: float -): - """ - Add a slide with some icons and text. - If no suitable icons are found, the step numbers are shown. - - :param presentation: The presentation object. - :param slide_json: The content of the slide as JSON data. - :param slide_width_inch: The width of the slide in inches. - :param slide_height_inch: The height of the slide in inches. - :return: True if the slide has been processed. - """ - - if 'bullet_points' in slide_json and slide_json['bullet_points']: - items = slide_json['bullet_points'] - - # Ensure that it is a single list of strings without any sub-list - for step in items: - if not isinstance(step, str) or not step.startswith(ICON_BEGINNING_MARKER): - return False - - slide_layout = presentation.slide_layouts[5] - slide = presentation.slides.add_slide(slide_layout) - slide.shapes.title.text = remove_slide_number_from_heading(slide_json['heading']) - - n_items = len(items) - text_box_size = INCHES_2 - - # Calculate the total width of all pictures and the spacing - total_width = n_items * ICON_SIZE - spacing = (pptx.util.Inches(slide_width_inch) - total_width) / (n_items + 1) - top = INCHES_3 - - icons_texts = [ - (match.group(1), match.group(2)) for match in [ - ICONS_REGEX.search(item) for item in items - ] - ] - fallback_icon_files = ice.find_icons([item[0] for item in icons_texts]) - - for idx, item in enumerate(icons_texts): - icon, accompanying_text = item - icon_path = f'{GlobalConfig.ICONS_DIR}/{icon}.png' - - if not os.path.exists(icon_path): - logger.warning( - 'Icon not found: %s...using fallback icon: %s', - icon, fallback_icon_files[idx] - ) - icon_path = f'{GlobalConfig.ICONS_DIR}/{fallback_icon_files[idx]}.png' - - left = spacing + idx * (ICON_SIZE + spacing) - # Calculate the center position for alignment - center = left + ICON_SIZE / 2 - - # Add a rectangle shape with a fill color (background) - # The size of the shape is slightly bigger than the icon, so align the icon position - shape = slide.shapes.add_shape( - MSO_AUTO_SHAPE_TYPE.ROUNDED_RECTANGLE, - center - INCHES_0_5, - top - (ICON_BG_SIZE - ICON_SIZE) / 2, - INCHES_1, INCHES_1 - ) - shape.fill.solid() - shape.shadow.inherit = False - - # Set the icon's background shape color - shape.fill.fore_color.rgb = shape.line.color.rgb = random.choice(ICON_COLORS) - - # Add the icon image on top of the colored shape - slide.shapes.add_picture(icon_path, left, top, height=ICON_SIZE) - - # Add a text box below the shape - text_box = slide.shapes.add_shape( - MSO_AUTO_SHAPE_TYPE.ROUNDED_RECTANGLE, - left=center - text_box_size / 2, # Center the text box horizontally - top=top + ICON_SIZE + INCHES_0_2, - width=text_box_size, - height=text_box_size - ) - text_frame = text_box.text_frame - text_frame.text = accompanying_text - text_frame.word_wrap = True - text_frame.paragraphs[0].alignment = pptx.enum.text.PP_ALIGN.CENTER - - # Center the text vertically - text_frame.vertical_anchor = pptx.enum.text.MSO_ANCHOR.MIDDLE - text_box.fill.background() # No fill - text_box.line.fill.background() # No line - text_box.shadow.inherit = False - - # Set the font color based on the theme - for paragraph in text_frame.paragraphs: - for run in paragraph.runs: - run.font.color.theme_color = pptx.enum.dml.MSO_THEME_COLOR.TEXT_2 - - _add_text_at_bottom( - slide=slide, - slide_width_inch=slide_width_inch, - slide_height_inch=slide_height_inch, - text='More icons available in the SlideDeck AI repository', - hyperlink='https://github.com/barun-saha/slide-deck-ai/tree/main/icons/png128' - ) - - return True - - return False - - -def _add_text_at_bottom( - slide: pptx.slide.Slide, - slide_width_inch: float, - slide_height_inch: float, - text: str, - hyperlink: Optional[str] = None, - target_height: Optional[float] = 0.5 -): - """ - Add arbitrary text to a textbox positioned near the lower left side of a slide. - - :param slide: The slide. - :param slide_width_inch: The width of the slide. - :param slide_height_inch: The height of the slide. - :param target_height: the target height of the box in inches (optional). - :param text: The text to be added - :param hyperlink: The hyperlink to be added to the text (optional). - """ - - footer = slide.shapes.add_textbox( - left=INCHES_1, - top=pptx.util.Inches(slide_height_inch - target_height), - width=pptx.util.Inches(slide_width_inch), - height=pptx.util.Inches(target_height) - ) - - paragraph = footer.text_frame.paragraphs[0] - run = paragraph.add_run() - run.text = text - run.font.size = pptx.util.Pt(10) - run.font.underline = False - - if hyperlink: - run.hyperlink.address = hyperlink - - -def _handle_double_col_layout( - presentation: pptx.Presentation(), - slide_json: dict, - slide_width_inch: float, - slide_height_inch: float -) -> bool: - """ - Add a slide with a double column layout for comparison. - - :param presentation: The presentation object. - :param slide_json: The content of the slide as JSON data. - :param slide_width_inch: The width of the slide in inches. - :param slide_height_inch: The height of the slide in inches. - :return: True if double col layout has been added; False otherwise. - """ - - if 'bullet_points' in slide_json and slide_json['bullet_points']: - double_col_content = slide_json['bullet_points'] - - if double_col_content and ( - len(double_col_content) == 2 - ) and isinstance(double_col_content[0], dict) and isinstance(double_col_content[1], dict): - slide = presentation.slide_layouts[4] - slide = presentation.slides.add_slide(slide) - placeholders = None - - shapes = slide.shapes - title_placeholder = shapes.title - title_placeholder.text = remove_slide_number_from_heading(slide_json['heading']) - - try: - left_heading, right_heading = shapes.placeholders[1], shapes.placeholders[3] - except KeyError: - # For manually edited/added master slides, the placeholder idx numbers in the dict - # will be different (>= 10) - left_heading, right_heading = None, None - placeholders = get_slide_placeholders(slide, layout_number=4) - - for idx, name in placeholders: - if 'text placeholder' in name: - if not left_heading: - left_heading = shapes.placeholders[idx] - elif not right_heading: - right_heading = shapes.placeholders[idx] - - try: - left_col, right_col = shapes.placeholders[2], shapes.placeholders[4] - except KeyError: - left_col, right_col = None, None - if not placeholders: - placeholders = get_slide_placeholders(slide, layout_number=4) - - for idx, name in placeholders: - if 'content placeholder' in name: - if not left_col: - left_col = shapes.placeholders[idx] - elif not right_col: - right_col = shapes.placeholders[idx] - - left_col_frame, right_col_frame = left_col.text_frame, right_col.text_frame - - if 'heading' in double_col_content[0] and left_heading: - left_heading.text = double_col_content[0]['heading'] - if 'bullet_points' in double_col_content[0]: - flat_items_list = get_flat_list_of_contents( - double_col_content[0]['bullet_points'], level=0 - ) - - if not left_heading: - left_col_frame.text = double_col_content[0]['heading'] - - for idx, an_item in enumerate(flat_items_list): - if left_heading and idx == 0: - left_col_frame.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - else: - paragraph = left_col_frame.add_paragraph() - paragraph.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - paragraph.level = an_item[1] - - if 'heading' in double_col_content[1] and right_heading: - right_heading.text = double_col_content[1]['heading'] - if 'bullet_points' in double_col_content[1]: - flat_items_list = get_flat_list_of_contents( - double_col_content[1]['bullet_points'], level=0 - ) - - if not right_heading: - right_col_frame.text = double_col_content[1]['heading'] - - for idx, an_item in enumerate(flat_items_list): - if right_col_frame and idx == 0: - right_col_frame.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - else: - paragraph = right_col_frame.add_paragraph() - paragraph.text = an_item[0].removeprefix(STEP_BY_STEP_PROCESS_MARKER) - paragraph.level = an_item[1] - - _handle_key_message( - the_slide=slide, - slide_json=slide_json, - slide_height_inch=slide_height_inch, - slide_width_inch=slide_width_inch - ) - - return True - - return False - - -def _handle_step_by_step_process( - presentation: pptx.Presentation, - slide_json: dict, - slide_width_inch: float, - slide_height_inch: float -) -> bool: - """ - Add shapes to display a step-by-step process in the slide, if available. - - :param presentation: The presentation object. - :param slide_json: The content of the slide as JSON data. - :param slide_width_inch: The width of the slide in inches. - :param slide_height_inch: The height of the slide in inches. - :return True if this slide has a step-by-step process depiction added; False otherwise. - """ - - if 'bullet_points' in slide_json and slide_json['bullet_points']: - steps = slide_json['bullet_points'] - - no_marker_count = 0.0 - n_steps = len(steps) - - # Ensure that it is a single list of strings without any sub-list - for step in steps: - if not isinstance(step, str): - return False - - # In some cases, one or two steps may not begin with >>, e.g.: - # { - # "heading": "Step-by-Step Process: Creating a Legacy", - # "bullet_points": [ - # "Identify your unique talents and passions", - # ">> Develop your skills and knowledge", - # ">> Create meaningful work", - # ">> Share your work with the world", - # ">> Continuously learn and adapt" - # ], - # "key_message": "" - # }, - # - # Use a threshold, e.g., at most 20% - if not step.startswith(STEP_BY_STEP_PROCESS_MARKER): - no_marker_count += 1 - - slide_header = slide_json['heading'].lower() - if (no_marker_count / n_steps > 0.25) and not ( - ('step-by-step' in slide_header) or ('step by step' in slide_header) - ): - return False - - if n_steps < 3 or n_steps > 6: - # Two steps -- probably not a process - # More than 5--6 steps -- would likely cause a visual clutter - return False - - bullet_slide_layout = presentation.slide_layouts[1] - slide = presentation.slides.add_slide(bullet_slide_layout) - shapes = slide.shapes - shapes.title.text = remove_slide_number_from_heading(slide_json['heading']) - - if 3 <= n_steps <= 4: - # Horizontal display - height = INCHES_1_5 - width = pptx.util.Inches(slide_width_inch / n_steps - 0.01) - top = pptx.util.Inches(slide_height_inch / 2) - left = pptx.util.Inches((slide_width_inch - width.inches * n_steps) / 2 + 0.05) - - for step in steps: - shape = shapes.add_shape(MSO_AUTO_SHAPE_TYPE.CHEVRON, left, top, width, height) - shape.text = step.removeprefix(STEP_BY_STEP_PROCESS_MARKER) - left += width - INCHES_0_4 - elif 4 < n_steps <= 6: - # Vertical display - height = pptx.util.Inches(0.65) - top = pptx.util.Inches(slide_height_inch / 4) - left = INCHES_1 # slide_width_inch - width.inches) - - # Find the close to median width, based on the length of each text, to be set - # for the shapes - width = pptx.util.Inches(slide_width_inch * 2 / 3) - lengths = [len(step) for step in steps] - font_size_20pt = pptx.util.Pt(20) - widths = sorted( - [ - min( - pptx.util.Inches(font_size_20pt.inches * a_len), - width - ) for a_len in lengths - ] - ) - width = widths[len(widths) // 2] - - for step in steps: - shape = shapes.add_shape(MSO_AUTO_SHAPE_TYPE.PENTAGON, left, top, width, height) - shape.text = step.removeprefix(STEP_BY_STEP_PROCESS_MARKER) - top += height + INCHES_0_3 - left += INCHES_0_5 - - return True - - -def _handle_key_message( - the_slide: pptx.slide.Slide, - slide_json: dict, - slide_width_inch: float, - slide_height_inch: float -): - """ - Add a shape to display the key message in the slide, if available. - - :param the_slide: The slide to be processed. - :param slide_json: The content of the slide as JSON data. - :param slide_width_inch: The width of the slide in inches. - :param slide_height_inch: The height of the slide in inches. - """ - - if 'key_message' in slide_json and slide_json['key_message']: - height = pptx.util.Inches(1.6) - width = pptx.util.Inches(slide_width_inch / 2.3) - top = pptx.util.Inches(slide_height_inch - height.inches - 0.1) - left = pptx.util.Inches((slide_width_inch - width.inches) / 2) - shape = the_slide.shapes.add_shape( - MSO_AUTO_SHAPE_TYPE.ROUNDED_RECTANGLE, - left=left, - top=top, - width=width, - height=height - ) - shape.text = slide_json['key_message'] - - -def _get_slide_width_height_inches(presentation: pptx.Presentation) -> Tuple[float, float]: - """ - Get the dimensions of a slide in inches. - - :param presentation: The presentation object. - :return: The width and the height. - """ - - slide_width_inch = EMU_TO_INCH_SCALING_FACTOR * presentation.slide_width - slide_height_inch = EMU_TO_INCH_SCALING_FACTOR * presentation.slide_height - # logger.debug('Slide width: %f, height: %f', slide_width_inch, slide_height_inch) - - return slide_width_inch, slide_height_inch - - -if __name__ == '__main__': - _JSON_DATA = ''' - { - "title": "AI Applications: Transforming Industries", - "slides": [ - { - "heading": "Introduction to AI Applications", - "bullet_points": [ - "Artificial Intelligence (AI) is transforming various industries", - "AI applications range from simple decision-making tools to complex systems", - "AI can be categorized into types: Rule-based, Instance-based, and Model-based" - ], - "key_message": "AI is a broad field with diverse applications and categories", - "img_keywords": "AI, transformation, industries, decision-making, categories" - }, - { - "heading": "AI in Everyday Life", - "bullet_points": [ - "Virtual assistants like Siri, Alexa, and Google Assistant", - "Recommender systems in Netflix, Amazon, and Spotify", - "Fraud detection in banking and credit card transactions" - ], - "key_message": "AI is integrated into our daily lives through various services", - "img_keywords": "virtual assistants, recommender systems, fraud detection" - }, - { - "heading": "AI in Healthcare", - "bullet_points": [ - "Disease diagnosis and prediction using machine learning algorithms", - "Personalized medicine and drug discovery", - "AI-powered robotic surgeries and remote patient monitoring" - ], - "key_message": "AI is revolutionizing healthcare with improved diagnostics and patient care", - "img_keywords": "healthcare, disease diagnosis, personalized medicine, robotic surgeries" - }, - { - "heading": "AI in Key Industries", - "bullet_points": [ - { - "heading": "Retail", - "bullet_points": [ - "Inventory management and demand forecasting", - "Customer segmentation and targeted marketing", - "AI-driven chatbots for customer service" - ] - }, - { - "heading": "Finance", - "bullet_points": [ - "Credit scoring and risk assessment", - "Algorithmic trading and portfolio management", - "AI for detecting money laundering and cyber fraud" - ] - } - ], - "key_message": "AI is transforming retail and finance with improved operations and decision-making", - "img_keywords": "retail, finance, inventory management, credit scoring, algorithmic trading" - }, - { - "heading": "AI in Education", - "bullet_points": [ - "Personalized learning paths and adaptive testing", - "Intelligent tutoring systems for skill development", - "AI for predicting student performance and dropout rates" - ], - "key_message": "AI is personalizing education and improving student outcomes", - }, - { - "heading": "Step-by-Step: AI Development Process", - "bullet_points": [ - ">> Define the problem and objectives", - ">> Collect and preprocess data", - ">> Select and train the AI model", - ">> Evaluate and optimize the model", - ">> Deploy and monitor the AI system" - ], - "key_message": "Developing AI involves a structured process from problem definition to deployment", - "img_keywords": "" - }, - { - "heading": "AI Icons: Key Aspects", - "bullet_points": [ - "[[brain]] Human-like intelligence and decision-making", - "[[robot]] Automation and physical tasks", - "[[]] Data processing and cloud computing", - "[[lightbulb]] Insights and predictions", - "[[globe2]] Global connectivity and impact" - ], - "key_message": "AI encompasses various aspects, from human-like intelligence to global impact", - "img_keywords": "AI aspects, intelligence, automation, data processing, global impact" - }, - { - "heading": "Conclusion: Embracing AI's Potential", - "bullet_points": [ - "AI is transforming industries and improving lives", - "Ethical considerations are crucial for responsible AI development", - "Invest in AI education and workforce development", - "Call to action: Explore AI applications and contribute to shaping its future" - ], - "key_message": "AI offers immense potential, and we must embrace it responsibly", - "img_keywords": "AI transformation, ethical considerations, AI education, future of AI" - } - ] -}''' - - temp = tempfile.NamedTemporaryFile(delete=False, suffix='.pptx') - path = pathlib.Path(temp.name) - - generate_powerpoint_presentation( - json5.loads(_JSON_DATA), - output_file_path=path, - slides_template='Basic' - ) - print(f'File path: {path}') - - temp.close() diff --git a/helpers/text_helper.py b/helpers/text_helper.py deleted file mode 100644 index 9ad6b8e643828beed0fb07818e0f67376a1eb3db..0000000000000000000000000000000000000000 --- a/helpers/text_helper.py +++ /dev/null @@ -1,89 +0,0 @@ -import json_repair as jr - - -def is_valid_prompt(prompt: str) -> bool: - """ - Verify whether user input satisfies the concerned constraints. - - :param prompt: The user input text. - :return: True if all criteria are satisfied; False otherwise. - """ - - if len(prompt) < 7 or ' ' not in prompt: - return False - - return True - - -def get_clean_json(json_str: str) -> str: - """ - Attempt to clean a JSON response string from the LLM by removing the trailing ``` - and any text beyond that. - CAUTION: May not be always accurate. - - :param json_str: The input string in JSON format. - :return: The "cleaned" JSON string. - """ - - # An example of response containing JSON and other text: - # { - # "title": "AI and the Future: A Transformative Journey", - # "slides": [ - # ... - # ] - # } <<---- This is end of valid JSON content - # ``` - # - # ```vbnet - # Please note that the JSON output is in valid format but the content of the "Role of GPUs in AI" slide is just an example and may not be factually accurate. For accurate information, you should consult relevant resources and update the content accordingly. - # ``` - response_cleaned = json_str - - while True: - idx = json_str.rfind('```') # -1 on failure - - if idx <= 0: - break - - # In the ideal scenario, the character before the last ``` should be - # a new line or a closing bracket } - prev_char = json_str[idx - 1] - - if (prev_char == '}') or (prev_char == '\n' and json_str[idx - 2] == '}'): - response_cleaned = json_str[:idx] - - json_str = json_str[:idx] - - return response_cleaned - - -def fix_malformed_json(json_str: str) -> str: - """ - Try and fix the syntax error(s) in a JSON string. - - :param json_str: The input JSON string. - :return: The fixed JSOn string. - """ - - return jr.repair_json(json_str, skip_json_loads=True) - - -if __name__ == '__main__': - json1 = '''{ - "key": "value" - } - ''' - json2 = '''["Reason": "Regular updates help protect against known vulnerabilities."]''' - json3 = '''["Reason" Regular updates help protect against known vulnerabilities."]''' - json4 = ''' - {"bullet_points": [ - ">> Write without stopping or editing", - >> Set daily writing goals and stick to them, - ">> Allow yourself to make mistakes" - ],} - ''' - - print(fix_malformed_json(json1)) - print(fix_malformed_json(json2)) - print(fix_malformed_json(json3)) - print(fix_malformed_json(json4)) diff --git a/icons/png128/0-circle.png b/icons/png128/0-circle.png deleted file mode 100644 index 54f47eb1eae9f340f4e6a612c7ac56ac715f48ef..0000000000000000000000000000000000000000 Binary files a/icons/png128/0-circle.png and /dev/null differ diff --git a/icons/png128/1-circle.png b/icons/png128/1-circle.png deleted file mode 100644 index fc5bf8551e6b9adb94b5c855c29416c8889c48cb..0000000000000000000000000000000000000000 Binary files a/icons/png128/1-circle.png and /dev/null differ diff --git a/icons/png128/123.png b/icons/png128/123.png deleted file mode 100644 index c398bcaeabb4ca8319b017491ce58e3cbb12c17a..0000000000000000000000000000000000000000 Binary files a/icons/png128/123.png and /dev/null differ diff --git a/icons/png128/2-circle.png b/icons/png128/2-circle.png deleted file mode 100644 index 0c23c949f76114c837f2963ec64f5d1d7fb6b8ac..0000000000000000000000000000000000000000 Binary files a/icons/png128/2-circle.png and /dev/null differ diff --git a/icons/png128/3-circle.png b/icons/png128/3-circle.png deleted file mode 100644 index bc8fb86a1c6514d55a9e8ab213a628c7978f86f5..0000000000000000000000000000000000000000 Binary files a/icons/png128/3-circle.png and /dev/null differ diff --git a/icons/png128/4-circle.png b/icons/png128/4-circle.png deleted file mode 100644 index 3e01f38654cc2020765e7c7941b37463aaf599de..0000000000000000000000000000000000000000 Binary files a/icons/png128/4-circle.png and /dev/null differ diff --git a/icons/png128/5-circle.png b/icons/png128/5-circle.png deleted file mode 100644 index 764078232850575eb31cd8b880d9c035916e35eb..0000000000000000000000000000000000000000 Binary files a/icons/png128/5-circle.png and /dev/null differ diff --git a/icons/png128/6-circle.png b/icons/png128/6-circle.png deleted file mode 100644 index 21969c5f8c2ca81ac78dd32df80eff6e23f7e699..0000000000000000000000000000000000000000 Binary files a/icons/png128/6-circle.png and /dev/null differ diff --git a/icons/png128/7-circle.png b/icons/png128/7-circle.png deleted file mode 100644 index 47244a9e177268563a3d22c3d20f3d548ccf9846..0000000000000000000000000000000000000000 Binary files a/icons/png128/7-circle.png and /dev/null differ diff --git a/icons/png128/8-circle.png b/icons/png128/8-circle.png deleted file mode 100644 index dec789bbe0ee0399159bbe4003b79f8e1f2633ca..0000000000000000000000000000000000000000 Binary files a/icons/png128/8-circle.png and /dev/null differ diff --git a/icons/png128/9-circle.png b/icons/png128/9-circle.png deleted file mode 100644 index 97ce7c79930e78396a6f7b2e3e3a1f5077d94886..0000000000000000000000000000000000000000 Binary files a/icons/png128/9-circle.png and /dev/null differ diff --git a/icons/png128/activity.png b/icons/png128/activity.png deleted file mode 100644 index 29d173caabfee8dbb024414671252eccc2bf6f5e..0000000000000000000000000000000000000000 Binary files a/icons/png128/activity.png and /dev/null differ diff --git a/icons/png128/airplane.png b/icons/png128/airplane.png deleted file mode 100644 index d99b0d657016d5803783eb3f9c7bad28770f0848..0000000000000000000000000000000000000000 Binary files a/icons/png128/airplane.png and /dev/null differ diff --git a/icons/png128/alarm.png b/icons/png128/alarm.png deleted file mode 100644 index 89634dbcb111f590e518b98bb45c1629867f32b6..0000000000000000000000000000000000000000 Binary files a/icons/png128/alarm.png and /dev/null differ diff --git a/icons/png128/alien-head.png b/icons/png128/alien-head.png deleted file mode 100644 index 4157dbc3527e3d5812a8f2e924774de9e2717409..0000000000000000000000000000000000000000 Binary files a/icons/png128/alien-head.png and /dev/null differ diff --git a/icons/png128/alphabet.png b/icons/png128/alphabet.png deleted file mode 100644 index 3fe4f1c0498ecb672182ff2740bc7da41eb93229..0000000000000000000000000000000000000000 Binary files a/icons/png128/alphabet.png and /dev/null differ diff --git a/icons/png128/amazon.png b/icons/png128/amazon.png deleted file mode 100644 index 8161b2c5dde25d37492b54c00d85d23ff992d1fd..0000000000000000000000000000000000000000 Binary files a/icons/png128/amazon.png and /dev/null differ diff --git a/icons/png128/amritsar-golden-temple.png b/icons/png128/amritsar-golden-temple.png deleted file mode 100644 index a20c63077c87ee47e3dbef9a6b95e7a9ee7ddf9e..0000000000000000000000000000000000000000 Binary files a/icons/png128/amritsar-golden-temple.png and /dev/null differ diff --git a/icons/png128/amsterdam-canal.png b/icons/png128/amsterdam-canal.png deleted file mode 100644 index e9bdcdab53a72796aeceb7bc83840bb651cd771b..0000000000000000000000000000000000000000 Binary files a/icons/png128/amsterdam-canal.png and /dev/null differ diff --git a/icons/png128/amsterdam-windmill.png b/icons/png128/amsterdam-windmill.png deleted file mode 100644 index bbe62de3aa1a55afe47fa76caaba56501f6b9439..0000000000000000000000000000000000000000 Binary files a/icons/png128/amsterdam-windmill.png and /dev/null differ diff --git a/icons/png128/android.png b/icons/png128/android.png deleted file mode 100644 index aac1a5407e30df19cb07e574a73fff333c90eaf9..0000000000000000000000000000000000000000 Binary files a/icons/png128/android.png and /dev/null differ diff --git a/icons/png128/angkor-wat.png b/icons/png128/angkor-wat.png deleted file mode 100644 index 3de33185794e5fae1e3bdd062f5e977b86e9773d..0000000000000000000000000000000000000000 Binary files a/icons/png128/angkor-wat.png and /dev/null differ diff --git a/icons/png128/apple.png b/icons/png128/apple.png deleted file mode 100644 index 0ac1512bac7d1b0c08bfc4813a87da851a5082e1..0000000000000000000000000000000000000000 Binary files a/icons/png128/apple.png and /dev/null differ diff --git a/icons/png128/archive.png b/icons/png128/archive.png deleted file mode 100644 index dad00d7ffca81e9a0172c2329228516cfa9b1534..0000000000000000000000000000000000000000 Binary files a/icons/png128/archive.png and /dev/null differ diff --git a/icons/png128/argentina-obelisk.png b/icons/png128/argentina-obelisk.png deleted file mode 100644 index e83d495b0a0ad7539bb7bab01049e550f6cf9ff7..0000000000000000000000000000000000000000 Binary files a/icons/png128/argentina-obelisk.png and /dev/null differ diff --git a/icons/png128/artificial-intelligence-brain.png b/icons/png128/artificial-intelligence-brain.png deleted file mode 100644 index 54feaaabf6dd103b24b3165347116a5b120f67e6..0000000000000000000000000000000000000000 Binary files a/icons/png128/artificial-intelligence-brain.png and /dev/null differ diff --git a/icons/png128/atlanta.png b/icons/png128/atlanta.png deleted file mode 100644 index b93bd7c4c1d1d418a77aa6f75584921911f28a7d..0000000000000000000000000000000000000000 Binary files a/icons/png128/atlanta.png and /dev/null differ diff --git a/icons/png128/austin.png b/icons/png128/austin.png deleted file mode 100644 index dd98b8dbf4fcf49f32e3568f44b7ff2e82c05251..0000000000000000000000000000000000000000 Binary files a/icons/png128/austin.png and /dev/null differ diff --git a/icons/png128/automation-decision.png b/icons/png128/automation-decision.png deleted file mode 100644 index 5f720671abfd46de14dc2b36ca0952e1155fb2e1..0000000000000000000000000000000000000000 Binary files a/icons/png128/automation-decision.png and /dev/null differ diff --git a/icons/png128/award.png b/icons/png128/award.png deleted file mode 100644 index 282c114e0adfa595a90f67a6cd7ec0df06b41937..0000000000000000000000000000000000000000 Binary files a/icons/png128/award.png and /dev/null differ diff --git a/icons/png128/balloon.png b/icons/png128/balloon.png deleted file mode 100644 index 430a0bd23b3bc95fe0ef4d0684536c45af3b621d..0000000000000000000000000000000000000000 Binary files a/icons/png128/balloon.png and /dev/null differ diff --git a/icons/png128/ban.png b/icons/png128/ban.png deleted file mode 100644 index 9f9ff0d59edcd335de08205789cda9d6b0c4c600..0000000000000000000000000000000000000000 Binary files a/icons/png128/ban.png and /dev/null differ diff --git a/icons/png128/bandaid.png b/icons/png128/bandaid.png deleted file mode 100644 index c3ca610d459cb55f08eb471afb0d42f1bba6bd12..0000000000000000000000000000000000000000 Binary files a/icons/png128/bandaid.png and /dev/null differ diff --git a/icons/png128/bangalore.png b/icons/png128/bangalore.png deleted file mode 100644 index 067ca74edfb054e4e61aeaa46e5610fe29da9284..0000000000000000000000000000000000000000 Binary files a/icons/png128/bangalore.png and /dev/null differ diff --git a/icons/png128/bank.png b/icons/png128/bank.png deleted file mode 100644 index 29623d64da5f34831adeb5be210c7a46afa18a1f..0000000000000000000000000000000000000000 Binary files a/icons/png128/bank.png and /dev/null differ diff --git a/icons/png128/bar-chart-line.png b/icons/png128/bar-chart-line.png deleted file mode 100644 index 790a7312a0c99ea3cc893f837298bfb069e6006e..0000000000000000000000000000000000000000 Binary files a/icons/png128/bar-chart-line.png and /dev/null differ diff --git a/icons/png128/barcelona.png b/icons/png128/barcelona.png deleted file mode 100644 index 05074b3e9e1b1d3ad28820930dc388661bd582eb..0000000000000000000000000000000000000000 Binary files a/icons/png128/barcelona.png and /dev/null differ diff --git a/icons/png128/basilica-of-the-sacred-heart.png b/icons/png128/basilica-of-the-sacred-heart.png deleted file mode 100644 index f9d9cd2a456f92c6875300745093c81c97b41560..0000000000000000000000000000000000000000 Binary files a/icons/png128/basilica-of-the-sacred-heart.png and /dev/null differ diff --git a/icons/png128/basket.png b/icons/png128/basket.png deleted file mode 100644 index f12d5e59093acfaea962037697d70214b3ff319a..0000000000000000000000000000000000000000 Binary files a/icons/png128/basket.png and /dev/null differ diff --git a/icons/png128/battery-charging.png b/icons/png128/battery-charging.png deleted file mode 100644 index 6653462a7bcf5de72c214b6d8701af937d9a3581..0000000000000000000000000000000000000000 Binary files a/icons/png128/battery-charging.png and /dev/null differ diff --git a/icons/png128/beijing-municipal.png b/icons/png128/beijing-municipal.png deleted file mode 100644 index 1d79742565cb51ffe6ac81f4f68db412cbd9e1bc..0000000000000000000000000000000000000000 Binary files a/icons/png128/beijing-municipal.png and /dev/null differ diff --git a/icons/png128/beijing-tower.png b/icons/png128/beijing-tower.png deleted file mode 100644 index fc5c5aad8b4750d93433697f31e84231f03cb483..0000000000000000000000000000000000000000 Binary files a/icons/png128/beijing-tower.png and /dev/null differ diff --git a/icons/png128/bell-slash.png b/icons/png128/bell-slash.png deleted file mode 100644 index 4d6573cb82a4227c6258c5af21b3cf866fbb001f..0000000000000000000000000000000000000000 Binary files a/icons/png128/bell-slash.png and /dev/null differ diff --git a/icons/png128/bell.png b/icons/png128/bell.png deleted file mode 100644 index 471edd200778ac45f92abfe7228cca4c5d0dcd4c..0000000000000000000000000000000000000000 Binary files a/icons/png128/bell.png and /dev/null differ diff --git a/icons/png128/berlin-cathedral.png b/icons/png128/berlin-cathedral.png deleted file mode 100644 index ad05ef3ac9367754135393a73df302f508142d71..0000000000000000000000000000000000000000 Binary files a/icons/png128/berlin-cathedral.png and /dev/null differ diff --git a/icons/png128/berlin-tower.png b/icons/png128/berlin-tower.png deleted file mode 100644 index 79de308342aa6a16fac1992d28f0dc990680869a..0000000000000000000000000000000000000000 Binary files a/icons/png128/berlin-tower.png and /dev/null differ diff --git a/icons/png128/bicycle.png b/icons/png128/bicycle.png deleted file mode 100644 index 9ccce6a065645beb69676611d900b0a91e1a16c3..0000000000000000000000000000000000000000 Binary files a/icons/png128/bicycle.png and /dev/null differ diff --git a/icons/png128/bing.png b/icons/png128/bing.png deleted file mode 100644 index 2214899be252e612843d5d57bdf9898a52a1bb03..0000000000000000000000000000000000000000 Binary files a/icons/png128/bing.png and /dev/null differ diff --git a/icons/png128/binoculars.png b/icons/png128/binoculars.png deleted file mode 100644 index 5fee8e59399eec136bec72fe5df8a3e6c9c23c5c..0000000000000000000000000000000000000000 Binary files a/icons/png128/binoculars.png and /dev/null differ diff --git a/icons/png128/blockchain.png b/icons/png128/blockchain.png deleted file mode 100644 index 16c025d7ad09e68afb232dbd618175d699494a4a..0000000000000000000000000000000000000000 Binary files a/icons/png128/blockchain.png and /dev/null differ diff --git a/icons/png128/bluetooth.png b/icons/png128/bluetooth.png deleted file mode 100644 index 0a9fb7d6565d99207340f4a551ac72e82c1eb623..0000000000000000000000000000000000000000 Binary files a/icons/png128/bluetooth.png and /dev/null differ diff --git a/icons/png128/book.png b/icons/png128/book.png deleted file mode 100644 index ef73c51cbb36cd540fe753bb38d9a451106f2957..0000000000000000000000000000000000000000 Binary files a/icons/png128/book.png and /dev/null differ diff --git a/icons/png128/bookmark.png b/icons/png128/bookmark.png deleted file mode 100644 index 1c4157b7e754e10c1ca96ff5661135a7461ed20d..0000000000000000000000000000000000000000 Binary files a/icons/png128/bookmark.png and /dev/null differ diff --git a/icons/png128/bootstrap.png b/icons/png128/bootstrap.png deleted file mode 100644 index e862c3042d0e14c6577ab9631fe2365156f5e703..0000000000000000000000000000000000000000 Binary files a/icons/png128/bootstrap.png and /dev/null differ diff --git a/icons/png128/boston-zakim-bridge.png b/icons/png128/boston-zakim-bridge.png deleted file mode 100644 index aaa1b9a288f242ee64d8f6739ade4482eabd0f3b..0000000000000000000000000000000000000000 Binary files a/icons/png128/boston-zakim-bridge.png and /dev/null differ diff --git a/icons/png128/brain.png b/icons/png128/brain.png deleted file mode 100644 index 18d1ccb7a54815b1d22851490c5fad50af36a7a0..0000000000000000000000000000000000000000 Binary files a/icons/png128/brain.png and /dev/null differ diff --git a/icons/png128/bread.png b/icons/png128/bread.png deleted file mode 100644 index 4f2f477189ea2a29421a780e98f9493224f3c3d8..0000000000000000000000000000000000000000 Binary files a/icons/png128/bread.png and /dev/null differ diff --git a/icons/png128/briefcase.png b/icons/png128/briefcase.png deleted file mode 100644 index 9bed1c0d4d84c2507660a1c884e8aae3995b0b72..0000000000000000000000000000000000000000 Binary files a/icons/png128/briefcase.png and /dev/null differ diff --git a/icons/png128/broadcast-pin.png b/icons/png128/broadcast-pin.png deleted file mode 100644 index 4abd2229b3b5996bd1e4b5827ea3ffd662827e81..0000000000000000000000000000000000000000 Binary files a/icons/png128/broadcast-pin.png and /dev/null differ diff --git a/icons/png128/browser-chrome.png b/icons/png128/browser-chrome.png deleted file mode 100644 index 0fb8d4b76a8f63db37f5d6b6edaa8d3103c7850e..0000000000000000000000000000000000000000 Binary files a/icons/png128/browser-chrome.png and /dev/null differ diff --git a/icons/png128/browser-edge.png b/icons/png128/browser-edge.png deleted file mode 100644 index b5332c5b562afeb59e665a7009b9294eb22d4c9d..0000000000000000000000000000000000000000 Binary files a/icons/png128/browser-edge.png and /dev/null differ diff --git a/icons/png128/browser-firefox.png b/icons/png128/browser-firefox.png deleted file mode 100644 index 898a502a00044e7a1724f2fd1950208035578f34..0000000000000000000000000000000000000000 Binary files a/icons/png128/browser-firefox.png and /dev/null differ diff --git a/icons/png128/browser-safari.png b/icons/png128/browser-safari.png deleted file mode 100644 index f9fc62833d0095cf7cb99d98589f27f085161d18..0000000000000000000000000000000000000000 Binary files a/icons/png128/browser-safari.png and /dev/null differ diff --git a/icons/png128/brush.png b/icons/png128/brush.png deleted file mode 100644 index f80c663eb1caf13e2196e3f2a585cdd57ddc92b1..0000000000000000000000000000000000000000 Binary files a/icons/png128/brush.png and /dev/null differ diff --git a/icons/png128/bucket.png b/icons/png128/bucket.png deleted file mode 100644 index aa435e13005e0bbcf3fd1900bb26df3f1b1523c2..0000000000000000000000000000000000000000 Binary files a/icons/png128/bucket.png and /dev/null differ diff --git a/icons/png128/budapest.png b/icons/png128/budapest.png deleted file mode 100644 index 2d5e3235b9ffabfd2f8445476440c82d2cbad145..0000000000000000000000000000000000000000 Binary files a/icons/png128/budapest.png and /dev/null differ diff --git a/icons/png128/bug-fill.png b/icons/png128/bug-fill.png deleted file mode 100644 index 41e14d6d8e4d286c63ccb4eb68be8271b83bc2c8..0000000000000000000000000000000000000000 Binary files a/icons/png128/bug-fill.png and /dev/null differ diff --git a/icons/png128/bug.png b/icons/png128/bug.png deleted file mode 100644 index 44fbe6f0630adefdba3a94840c0a9b5bc7a978d6..0000000000000000000000000000000000000000 Binary files a/icons/png128/bug.png and /dev/null differ diff --git a/icons/png128/building.png b/icons/png128/building.png deleted file mode 100644 index 3a07874b1e912dd1771dcc6e17b1381fbcee4aa2..0000000000000000000000000000000000000000 Binary files a/icons/png128/building.png and /dev/null differ diff --git a/icons/png128/bullseye.png b/icons/png128/bullseye.png deleted file mode 100644 index cac1147bbb0af22f9e87c37321b8377eafa0256b..0000000000000000000000000000000000000000 Binary files a/icons/png128/bullseye.png and /dev/null differ diff --git a/icons/png128/burger.png b/icons/png128/burger.png deleted file mode 100644 index e9f886e66cad2c25d496143b8e8c9f64ae4b45f4..0000000000000000000000000000000000000000 Binary files a/icons/png128/burger.png and /dev/null differ diff --git a/icons/png128/bus-front.png b/icons/png128/bus-front.png deleted file mode 100644 index 5fcf88594732e1deb9972fca01932639e97ce4fb..0000000000000000000000000000000000000000 Binary files a/icons/png128/bus-front.png and /dev/null differ diff --git a/icons/png128/cafe.png b/icons/png128/cafe.png deleted file mode 100644 index bd349a8abe92170690fdfefc54f7723d7dfa2d2c..0000000000000000000000000000000000000000 Binary files a/icons/png128/cafe.png and /dev/null differ diff --git a/icons/png128/cairo-giza-plateau.png b/icons/png128/cairo-giza-plateau.png deleted file mode 100644 index 3ffced13658c54948aeaa7e82843666bba57d0eb..0000000000000000000000000000000000000000 Binary files a/icons/png128/cairo-giza-plateau.png and /dev/null differ diff --git a/icons/png128/cake2.png b/icons/png128/cake2.png deleted file mode 100644 index 70f1ab92e3d3c7dd413a33d206b03c45c9aa6b80..0000000000000000000000000000000000000000 Binary files a/icons/png128/cake2.png and /dev/null differ diff --git a/icons/png128/calculator.png b/icons/png128/calculator.png deleted file mode 100644 index b33c415bd454282040c95ef2d8a4b17b738d62b2..0000000000000000000000000000000000000000 Binary files a/icons/png128/calculator.png and /dev/null differ diff --git a/icons/png128/calendar.png b/icons/png128/calendar.png deleted file mode 100644 index 03b5f249350e8b7cd4a68e0ec947754d1d185e5d..0000000000000000000000000000000000000000 Binary files a/icons/png128/calendar.png and /dev/null differ diff --git a/icons/png128/camera.png b/icons/png128/camera.png deleted file mode 100644 index cb3192ecb48728c42a632b56b35376a4c9a46ece..0000000000000000000000000000000000000000 Binary files a/icons/png128/camera.png and /dev/null differ diff --git a/icons/png128/capitol.png b/icons/png128/capitol.png deleted file mode 100644 index f8fb4979e6a1fa2ffa5caad177d87e89ac184a26..0000000000000000000000000000000000000000 Binary files a/icons/png128/capitol.png and /dev/null differ diff --git a/icons/png128/card-image.png b/icons/png128/card-image.png deleted file mode 100644 index 66d81d99388b220ff444f21a46247a2e306a23ff..0000000000000000000000000000000000000000 Binary files a/icons/png128/card-image.png and /dev/null differ diff --git a/icons/png128/cardiogram.png b/icons/png128/cardiogram.png deleted file mode 100644 index eb11c771a732634c849457ed9e8744943c810aa9..0000000000000000000000000000000000000000 Binary files a/icons/png128/cardiogram.png and /dev/null differ diff --git a/icons/png128/cart.png b/icons/png128/cart.png deleted file mode 100644 index 9b25a75e7d982c61783afc4c2422fc5168058015..0000000000000000000000000000000000000000 Binary files a/icons/png128/cart.png and /dev/null differ diff --git a/icons/png128/certificate.png b/icons/png128/certificate.png deleted file mode 100644 index 9da53fc2d3a116e384011ece5a43eef913811ee7..0000000000000000000000000000000000000000 Binary files a/icons/png128/certificate.png and /dev/null differ diff --git a/icons/png128/christ-the-redeemer.png b/icons/png128/christ-the-redeemer.png deleted file mode 100644 index 7ed51d3f19e1ffe7d361b0d783bd48c1e68b0877..0000000000000000000000000000000000000000 Binary files a/icons/png128/christ-the-redeemer.png and /dev/null differ diff --git a/icons/png128/clipboard-check.png b/icons/png128/clipboard-check.png deleted file mode 100644 index b1544d00819526a4d23f7a1137441deff9a66c3b..0000000000000000000000000000000000000000 Binary files a/icons/png128/clipboard-check.png and /dev/null differ diff --git a/icons/png128/clock.png b/icons/png128/clock.png deleted file mode 100644 index 70b323c268fab45dbd87e98c5a2d4385a4c67492..0000000000000000000000000000000000000000 Binary files a/icons/png128/clock.png and /dev/null differ diff --git a/icons/png128/cloud-moon.png b/icons/png128/cloud-moon.png deleted file mode 100644 index 4781ae81fd4553fbdab4760a79cc3fdf6b4280ca..0000000000000000000000000000000000000000 Binary files a/icons/png128/cloud-moon.png and /dev/null differ diff --git a/icons/png128/cloud-sun.png b/icons/png128/cloud-sun.png deleted file mode 100644 index 5ed28c28e04dabcfd2f9b6144055dc801b9c28a0..0000000000000000000000000000000000000000 Binary files a/icons/png128/cloud-sun.png and /dev/null differ diff --git a/icons/png128/cloud.png b/icons/png128/cloud.png deleted file mode 100644 index edf3442d35a9d6d30a96f1f6211d1911296a0e29..0000000000000000000000000000000000000000 Binary files a/icons/png128/cloud.png and /dev/null differ diff --git a/icons/png128/clusters.png b/icons/png128/clusters.png deleted file mode 100644 index dfcb1c243a7e95c70e25821b11927c713aa2e71e..0000000000000000000000000000000000000000 Binary files a/icons/png128/clusters.png and /dev/null differ diff --git a/icons/png128/code.png b/icons/png128/code.png deleted file mode 100644 index 7372f5fa90fec510dfd859f658035b262d1b6690..0000000000000000000000000000000000000000 Binary files a/icons/png128/code.png and /dev/null differ diff --git a/icons/png128/compass.png b/icons/png128/compass.png deleted file mode 100644 index 9d96b2795200410e037495c13483b6ed4b5d6c09..0000000000000000000000000000000000000000 Binary files a/icons/png128/compass.png and /dev/null differ diff --git a/icons/png128/computer-tv.png b/icons/png128/computer-tv.png deleted file mode 100644 index 159533edf37637034c59d35ef77b8a72128728a8..0000000000000000000000000000000000000000 Binary files a/icons/png128/computer-tv.png and /dev/null differ diff --git a/icons/png128/cone-striped.png b/icons/png128/cone-striped.png deleted file mode 100644 index 071731457c881c77d7c35d2b4c5315f1716cefa0..0000000000000000000000000000000000000000 Binary files a/icons/png128/cone-striped.png and /dev/null differ diff --git a/icons/png128/conversation.png b/icons/png128/conversation.png deleted file mode 100644 index 9d37b276cea40d3cd6947d72d9fb26a23643d0a0..0000000000000000000000000000000000000000 Binary files a/icons/png128/conversation.png and /dev/null differ diff --git a/icons/png128/cpu-fill.png b/icons/png128/cpu-fill.png deleted file mode 100644 index 7d17ba0074f9a72275ad9017a7cb19d563842836..0000000000000000000000000000000000000000 Binary files a/icons/png128/cpu-fill.png and /dev/null differ diff --git a/icons/png128/cpu.png b/icons/png128/cpu.png deleted file mode 100644 index 9f1edee055520f770087c51e49b7aae6d02133fb..0000000000000000000000000000000000000000 Binary files a/icons/png128/cpu.png and /dev/null differ diff --git a/icons/png128/credit-card.png b/icons/png128/credit-card.png deleted file mode 100644 index ab97cecd076f0f829cf958096ca9ef218aec23fb..0000000000000000000000000000000000000000 Binary files a/icons/png128/credit-card.png and /dev/null differ diff --git a/icons/png128/csv.png b/icons/png128/csv.png deleted file mode 100644 index b346ebcf2d78908c8a3c1cca05efe2d88a08aecc..0000000000000000000000000000000000000000 Binary files a/icons/png128/csv.png and /dev/null differ diff --git a/icons/png128/cup.png b/icons/png128/cup.png deleted file mode 100644 index 8d3cd3c5d2190e146b25877e2b195208fde7047d..0000000000000000000000000000000000000000 Binary files a/icons/png128/cup.png and /dev/null differ diff --git a/icons/png128/currency-bitcoin.png b/icons/png128/currency-bitcoin.png deleted file mode 100644 index 34ca9616beab6db0eece5f7dc36b6064af31372c..0000000000000000000000000000000000000000 Binary files a/icons/png128/currency-bitcoin.png and /dev/null differ diff --git a/icons/png128/currency-dollar.png b/icons/png128/currency-dollar.png deleted file mode 100644 index 14fbd46eb110c2446e4c06c4482ebee22a4c1907..0000000000000000000000000000000000000000 Binary files a/icons/png128/currency-dollar.png and /dev/null differ diff --git a/icons/png128/currency-euro.png b/icons/png128/currency-euro.png deleted file mode 100644 index 6113911b9019d16b4468ba6c182f5327c716e22e..0000000000000000000000000000000000000000 Binary files a/icons/png128/currency-euro.png and /dev/null differ diff --git a/icons/png128/currency-exchange.png b/icons/png128/currency-exchange.png deleted file mode 100644 index 88fc82fa7bdc3ed7d8d3f649af65d01b73bcf0f2..0000000000000000000000000000000000000000 Binary files a/icons/png128/currency-exchange.png and /dev/null differ diff --git a/icons/png128/currency-pound.png b/icons/png128/currency-pound.png deleted file mode 100644 index 13276f42a59856b81efc7a61c716c23280de41b5..0000000000000000000000000000000000000000 Binary files a/icons/png128/currency-pound.png and /dev/null differ diff --git a/icons/png128/currency-rupee.png b/icons/png128/currency-rupee.png deleted file mode 100644 index b9b3912402fbce34d5ee378f1f205492467ac2db..0000000000000000000000000000000000000000 Binary files a/icons/png128/currency-rupee.png and /dev/null differ diff --git a/icons/png128/currency-yen.png b/icons/png128/currency-yen.png deleted file mode 100644 index 7afd975ce7d24026d133d226c6b4eff0f6fa5566..0000000000000000000000000000000000000000 Binary files a/icons/png128/currency-yen.png and /dev/null differ diff --git a/icons/png128/dash-circle.png b/icons/png128/dash-circle.png deleted file mode 100644 index c2146bafb02f7bc412949cc01dda70713cb0f64a..0000000000000000000000000000000000000000 Binary files a/icons/png128/dash-circle.png and /dev/null differ diff --git a/icons/png128/data-document.png b/icons/png128/data-document.png deleted file mode 100644 index d8eb0726e7583ec0efeed54ed11aa3f83fbd47e9..0000000000000000000000000000000000000000 Binary files a/icons/png128/data-document.png and /dev/null differ diff --git a/icons/png128/database.png b/icons/png128/database.png deleted file mode 100644 index 509e8e0c4666c8fa2ba2788a5ac651509b3827c5..0000000000000000000000000000000000000000 Binary files a/icons/png128/database.png and /dev/null differ diff --git a/icons/png128/deep-learning.png b/icons/png128/deep-learning.png deleted file mode 100644 index 9d90b773b371e283f7154ec4701b2f67b169f9c2..0000000000000000000000000000000000000000 Binary files a/icons/png128/deep-learning.png and /dev/null differ diff --git a/icons/png128/delhi-humayun-tomb.png b/icons/png128/delhi-humayun-tomb.png deleted file mode 100644 index af0a8a5d9181917d6221ff362bed4f660fe3313f..0000000000000000000000000000000000000000 Binary files a/icons/png128/delhi-humayun-tomb.png and /dev/null differ diff --git a/icons/png128/delhi-jama-masjid.png b/icons/png128/delhi-jama-masjid.png deleted file mode 100644 index 84c860e6d94f912f43bcbb63d7757459de106325..0000000000000000000000000000000000000000 Binary files a/icons/png128/delhi-jama-masjid.png and /dev/null differ diff --git a/icons/png128/delhi-jantar-mantar.png b/icons/png128/delhi-jantar-mantar.png deleted file mode 100644 index 79c30189a3db5255c4cf6c855160d7ed9236b52c..0000000000000000000000000000000000000000 Binary files a/icons/png128/delhi-jantar-mantar.png and /dev/null differ diff --git a/icons/png128/delhi-lotus-temple.png b/icons/png128/delhi-lotus-temple.png deleted file mode 100644 index c562c4dcf995e6def58e77ae5984bbff9df82fdc..0000000000000000000000000000000000000000 Binary files a/icons/png128/delhi-lotus-temple.png and /dev/null differ diff --git a/icons/png128/delhi-red-fort.png b/icons/png128/delhi-red-fort.png deleted file mode 100644 index 16d2844099550d514591335423afbb178e04b1b1..0000000000000000000000000000000000000000 Binary files a/icons/png128/delhi-red-fort.png and /dev/null differ diff --git a/icons/png128/device-ssd.png b/icons/png128/device-ssd.png deleted file mode 100644 index ec2533109e8e0dbe7516e754f06c187c1224e44f..0000000000000000000000000000000000000000 Binary files a/icons/png128/device-ssd.png and /dev/null differ diff --git a/icons/png128/display.png b/icons/png128/display.png deleted file mode 100644 index 94dbf7cbd09b74d45383b9d1cadfe197300c2a22..0000000000000000000000000000000000000000 Binary files a/icons/png128/display.png and /dev/null differ diff --git a/icons/png128/dna.png b/icons/png128/dna.png deleted file mode 100644 index 2eafe7de5fe821a4ff87443e6d8556da231be16f..0000000000000000000000000000000000000000 Binary files a/icons/png128/dna.png and /dev/null differ diff --git a/icons/png128/doctor-patient.png b/icons/png128/doctor-patient.png deleted file mode 100644 index 9af6f48e7f140b0550371222bbfb0312f4d4748e..0000000000000000000000000000000000000000 Binary files a/icons/png128/doctor-patient.png and /dev/null differ diff --git a/icons/png128/donut.png b/icons/png128/donut.png deleted file mode 100644 index c1e42a28cbb6da5aef61e2a6b12aa49b2f5b8220..0000000000000000000000000000000000000000 Binary files a/icons/png128/donut.png and /dev/null differ diff --git a/icons/png128/drone.png b/icons/png128/drone.png deleted file mode 100644 index 5efdc4e82c8ab979cc08292ba6f0b7a4dba79a43..0000000000000000000000000000000000000000 Binary files a/icons/png128/drone.png and /dev/null differ diff --git a/icons/png128/dublin-castle.png b/icons/png128/dublin-castle.png deleted file mode 100644 index c4ae58df9f9ed632c7e5afc8c289714aa3bb8f53..0000000000000000000000000000000000000000 Binary files a/icons/png128/dublin-castle.png and /dev/null differ diff --git a/icons/png128/ecuador-quito.png b/icons/png128/ecuador-quito.png deleted file mode 100644 index 68afcd9b35d88be71ba5b578aae89208c37012d3..0000000000000000000000000000000000000000 Binary files a/icons/png128/ecuador-quito.png and /dev/null differ diff --git a/icons/png128/eiffel-tower-travel.png b/icons/png128/eiffel-tower-travel.png deleted file mode 100644 index 09914fa1c45cd17f6322c81bad8561358e864d86..0000000000000000000000000000000000000000 Binary files a/icons/png128/eiffel-tower-travel.png and /dev/null differ diff --git a/icons/png128/envelope.png b/icons/png128/envelope.png deleted file mode 100644 index 1c9fe342c58e6568e0b17b7246333ef46aa8219a..0000000000000000000000000000000000000000 Binary files a/icons/png128/envelope.png and /dev/null differ diff --git a/icons/png128/escalator-up.png b/icons/png128/escalator-up.png deleted file mode 100644 index 4f33f3723408510798d9f1695a6b17132072e3b0..0000000000000000000000000000000000000000 Binary files a/icons/png128/escalator-up.png and /dev/null differ diff --git a/icons/png128/ev-station.png b/icons/png128/ev-station.png deleted file mode 100644 index 10cd0de9398f6516cf6a2c35e9f5f8c1941fa3fb..0000000000000000000000000000000000000000 Binary files a/icons/png128/ev-station.png and /dev/null differ diff --git a/icons/png128/exclamation-triangle.png b/icons/png128/exclamation-triangle.png deleted file mode 100644 index 5c9484fb959d67c8aa01f2383d048f00152a0ee3..0000000000000000000000000000000000000000 Binary files a/icons/png128/exclamation-triangle.png and /dev/null differ diff --git a/icons/png128/eye.png b/icons/png128/eye.png deleted file mode 100644 index 789d385559bb796d199f10e8da34e527adf64b48..0000000000000000000000000000000000000000 Binary files a/icons/png128/eye.png and /dev/null differ diff --git a/icons/png128/facebook.png b/icons/png128/facebook.png deleted file mode 100644 index 2d61f4e7351c05d4422f300796e791f1f9b51bb9..0000000000000000000000000000000000000000 Binary files a/icons/png128/facebook.png and /dev/null differ diff --git a/icons/png128/fairness.png b/icons/png128/fairness.png deleted file mode 100644 index 573b530179dd455736969714b2b4c6e2fef5fbcd..0000000000000000000000000000000000000000 Binary files a/icons/png128/fairness.png and /dev/null differ diff --git a/icons/png128/farmer.png b/icons/png128/farmer.png deleted file mode 100644 index ef6361b4a44d0c24cf7cd57fc16adb0d1bc27df9..0000000000000000000000000000000000000000 Binary files a/icons/png128/farmer.png and /dev/null differ diff --git a/icons/png128/feather.png b/icons/png128/feather.png deleted file mode 100644 index d4d6b37a59b8ce3f889b47936ca218067990d352..0000000000000000000000000000000000000000 Binary files a/icons/png128/feather.png and /dev/null differ diff --git a/icons/png128/finance-strategy.png b/icons/png128/finance-strategy.png deleted file mode 100644 index bbf3c43e0805e7730d6bfb7b50c756d90856c526..0000000000000000000000000000000000000000 Binary files a/icons/png128/finance-strategy.png and /dev/null differ diff --git a/icons/png128/fingerprint.png b/icons/png128/fingerprint.png deleted file mode 100644 index 599a5da3f3816c01e7548704ad94822b555c62c6..0000000000000000000000000000000000000000 Binary files a/icons/png128/fingerprint.png and /dev/null differ diff --git a/icons/png128/fire.png b/icons/png128/fire.png deleted file mode 100644 index 6c367a871592ce3183a093d509a241ad9d973c43..0000000000000000000000000000000000000000 Binary files a/icons/png128/fire.png and /dev/null differ diff --git a/icons/png128/flag.png b/icons/png128/flag.png deleted file mode 100644 index 2aae6912ae304e8e1cdec7479da500fc99d8f7a6..0000000000000000000000000000000000000000 Binary files a/icons/png128/flag.png and /dev/null differ diff --git a/icons/png128/flask.png b/icons/png128/flask.png deleted file mode 100644 index b6a8eb224e611962d9684fd711030b57825d4c3e..0000000000000000000000000000000000000000 Binary files a/icons/png128/flask.png and /dev/null differ diff --git a/icons/png128/floppy.png b/icons/png128/floppy.png deleted file mode 100644 index 417862a92062152115a6638d494ba524aded969a..0000000000000000000000000000000000000000 Binary files a/icons/png128/floppy.png and /dev/null differ diff --git a/icons/png128/flower.png b/icons/png128/flower.png deleted file mode 100644 index 8e1a86e2ed8389ffc652a309ea5bac317f7bbf4c..0000000000000000000000000000000000000000 Binary files a/icons/png128/flower.png and /dev/null differ diff --git a/icons/png128/folder.png b/icons/png128/folder.png deleted file mode 100644 index 2108e64b3ac2253d88a8bf6ad0f4d65cffc52199..0000000000000000000000000000000000000000 Binary files a/icons/png128/folder.png and /dev/null differ diff --git a/icons/png128/french.png b/icons/png128/french.png deleted file mode 100644 index f2b1642ce90a8dd089c670a28e1d82411f5518ff..0000000000000000000000000000000000000000 Binary files a/icons/png128/french.png and /dev/null differ diff --git a/icons/png128/fried.png b/icons/png128/fried.png deleted file mode 100644 index e4a1f1bf8abdf3905cc30fb28413b89f56ea1d50..0000000000000000000000000000000000000000 Binary files a/icons/png128/fried.png and /dev/null differ diff --git a/icons/png128/funnel.png b/icons/png128/funnel.png deleted file mode 100644 index e68c290a0f92bfa83b44b43ecd6cae33f420820d..0000000000000000000000000000000000000000 Binary files a/icons/png128/funnel.png and /dev/null differ diff --git a/icons/png128/game-controller.png b/icons/png128/game-controller.png deleted file mode 100644 index a67c7e9a0265dde4bb043a8710ad0ea09a3b0698..0000000000000000000000000000000000000000 Binary files a/icons/png128/game-controller.png and /dev/null differ diff --git a/icons/png128/gate-of-india-mumbai.png b/icons/png128/gate-of-india-mumbai.png deleted file mode 100644 index 6927018a154c93d616ce356f00a4d7a4f44bb32a..0000000000000000000000000000000000000000 Binary files a/icons/png128/gate-of-india-mumbai.png and /dev/null differ diff --git a/icons/png128/gear-wide.png b/icons/png128/gear-wide.png deleted file mode 100644 index 41b616ead514eca32635247352f8be7fb615c798..0000000000000000000000000000000000000000 Binary files a/icons/png128/gear-wide.png and /dev/null differ diff --git a/icons/png128/gem.png b/icons/png128/gem.png deleted file mode 100644 index bd7b34a69c6140d3e662f300cc3f77114015eed8..0000000000000000000000000000000000000000 Binary files a/icons/png128/gem.png and /dev/null differ diff --git a/icons/png128/geo-alt.png b/icons/png128/geo-alt.png deleted file mode 100644 index 2d46517d070373677d5557c90543ddac1e871287..0000000000000000000000000000000000000000 Binary files a/icons/png128/geo-alt.png and /dev/null differ diff --git a/icons/png128/github.png b/icons/png128/github.png deleted file mode 100644 index efeb414441acfcea1bd2ef3c483f9a79b808d64c..0000000000000000000000000000000000000000 Binary files a/icons/png128/github.png and /dev/null differ diff --git a/icons/png128/glasses.png b/icons/png128/glasses.png deleted file mode 100644 index befe207a9e229da114bb407798e044484603aecd..0000000000000000000000000000000000000000 Binary files a/icons/png128/glasses.png and /dev/null differ diff --git a/icons/png128/globe.png b/icons/png128/globe.png deleted file mode 100644 index 1cd1e356c13326761c93ebbed508b51580ba0f9d..0000000000000000000000000000000000000000 Binary files a/icons/png128/globe.png and /dev/null differ diff --git a/icons/png128/gloves.png b/icons/png128/gloves.png deleted file mode 100644 index 81e7b0181f55a81cd7af54ba1ae3a420ae658339..0000000000000000000000000000000000000000 Binary files a/icons/png128/gloves.png and /dev/null differ diff --git a/icons/png128/google.png b/icons/png128/google.png deleted file mode 100644 index 38aade8312bae18d56fd0fa752ee9b6ae103957d..0000000000000000000000000000000000000000 Binary files a/icons/png128/google.png and /dev/null differ diff --git a/icons/png128/graph-down-arrow.png b/icons/png128/graph-down-arrow.png deleted file mode 100644 index 7c10f4a3b9bb461a8cdba3c7dccd8cf848862940..0000000000000000000000000000000000000000 Binary files a/icons/png128/graph-down-arrow.png and /dev/null differ diff --git a/icons/png128/graph-up-arrow.png b/icons/png128/graph-up-arrow.png deleted file mode 100644 index adab0c9520d11e835da7d478c02fe28193bedc60..0000000000000000000000000000000000000000 Binary files a/icons/png128/graph-up-arrow.png and /dev/null differ diff --git a/icons/png128/graphene-carbon.png b/icons/png128/graphene-carbon.png deleted file mode 100644 index 972c9b0bb865b6fa66dab4dc2fff004a0b6eb575..0000000000000000000000000000000000000000 Binary files a/icons/png128/graphene-carbon.png and /dev/null differ diff --git a/icons/png128/great-buddha-of-thailand-thailand.png b/icons/png128/great-buddha-of-thailand-thailand.png deleted file mode 100644 index 8ffa125c231f0b0e130a00b6bbd23b160b6b349c..0000000000000000000000000000000000000000 Binary files a/icons/png128/great-buddha-of-thailand-thailand.png and /dev/null differ diff --git a/icons/png128/great-wall-of-china.png b/icons/png128/great-wall-of-china.png deleted file mode 100644 index f881ea85b965baa4ebe5a475bf092c3b2f3a394c..0000000000000000000000000000000000000000 Binary files a/icons/png128/great-wall-of-china.png and /dev/null differ diff --git a/icons/png128/grid-3x3-gap.png b/icons/png128/grid-3x3-gap.png deleted file mode 100644 index 346a802691331a3d55dff43abe1a732d1f2c1d2c..0000000000000000000000000000000000000000 Binary files a/icons/png128/grid-3x3-gap.png and /dev/null differ diff --git a/icons/png128/hammer.png b/icons/png128/hammer.png deleted file mode 100644 index 11a37117ced2b07bcac9ba8a45e63d08f5061296..0000000000000000000000000000000000000000 Binary files a/icons/png128/hammer.png and /dev/null differ diff --git a/icons/png128/handbag.png b/icons/png128/handbag.png deleted file mode 100644 index 8aeda881bd702edeb6804d7e7f616b9465ee7f27..0000000000000000000000000000000000000000 Binary files a/icons/png128/handbag.png and /dev/null differ diff --git a/icons/png128/handshake.png b/icons/png128/handshake.png deleted file mode 100644 index 7dea86e0b792f7efe9af5976b409edc802a195fb..0000000000000000000000000000000000000000 Binary files a/icons/png128/handshake.png and /dev/null differ diff --git a/icons/png128/hassan-mosque-morocco.png b/icons/png128/hassan-mosque-morocco.png deleted file mode 100644 index b7d1c827de4286e333510523cd6251cfea10aaf1..0000000000000000000000000000000000000000 Binary files a/icons/png128/hassan-mosque-morocco.png and /dev/null differ diff --git a/icons/png128/headset.png b/icons/png128/headset.png deleted file mode 100644 index 3a52f69217d08116ebcd7298e07fe24727ac9de7..0000000000000000000000000000000000000000 Binary files a/icons/png128/headset.png and /dev/null differ diff --git a/icons/png128/heart.png b/icons/png128/heart.png deleted file mode 100644 index e9aa685df428098bcc46a5bf8d6a7042cb482598..0000000000000000000000000000000000000000 Binary files a/icons/png128/heart.png and /dev/null differ diff --git a/icons/png128/heartbreak.png b/icons/png128/heartbreak.png deleted file mode 100644 index b5ddc37c7971e685b1258e8425311e58c4c3b20d..0000000000000000000000000000000000000000 Binary files a/icons/png128/heartbreak.png and /dev/null differ diff --git a/icons/png128/hong-kong.png b/icons/png128/hong-kong.png deleted file mode 100644 index a33ecc5370c04e9a72e07b8d85990cfe8fc04850..0000000000000000000000000000000000000000 Binary files a/icons/png128/hong-kong.png and /dev/null differ diff --git a/icons/png128/hospital.png b/icons/png128/hospital.png deleted file mode 100644 index d6c17fa4364b5605e2132ecb7f92a8e1695f527e..0000000000000000000000000000000000000000 Binary files a/icons/png128/hospital.png and /dev/null differ diff --git a/icons/png128/hotdog.png b/icons/png128/hotdog.png deleted file mode 100644 index f4327e6085931cc0d7538ba8571f414988a91dd0..0000000000000000000000000000000000000000 Binary files a/icons/png128/hotdog.png and /dev/null differ diff --git a/icons/png128/hourglass-split.png b/icons/png128/hourglass-split.png deleted file mode 100644 index a1fbbb716c7289b789004fa0064a2410d98927cf..0000000000000000000000000000000000000000 Binary files a/icons/png128/hourglass-split.png and /dev/null differ diff --git a/icons/png128/house.png b/icons/png128/house.png deleted file mode 100644 index 5be282e94b6b438e6f5b6472c1311ab4bfdda308..0000000000000000000000000000000000000000 Binary files a/icons/png128/house.png and /dev/null differ diff --git a/icons/png128/html.png b/icons/png128/html.png deleted file mode 100644 index a0c0f7ed79f4190946eabac756157eeffc01ba88..0000000000000000000000000000000000000000 Binary files a/icons/png128/html.png and /dev/null differ diff --git a/icons/png128/ice-cream.png b/icons/png128/ice-cream.png deleted file mode 100644 index 3cb641d79a5be2e7f4e0c8b74f895b75f3355c09..0000000000000000000000000000000000000000 Binary files a/icons/png128/ice-cream.png and /dev/null differ diff --git a/icons/png128/image.png b/icons/png128/image.png deleted file mode 100644 index c33ae438246b7400badc8f43540aa295ebd00765..0000000000000000000000000000000000000000 Binary files a/icons/png128/image.png and /dev/null differ diff --git a/icons/png128/india-ganges.png b/icons/png128/india-ganges.png deleted file mode 100644 index 0da08c2e3d58b1cc0d52aec04580b6290ffe55ca..0000000000000000000000000000000000000000 Binary files a/icons/png128/india-ganges.png and /dev/null differ diff --git a/icons/png128/jaipur-hawa-mahal.png b/icons/png128/jaipur-hawa-mahal.png deleted file mode 100644 index 3ff63fcaa718f8b5a216320cbd8566b3f8f52804..0000000000000000000000000000000000000000 Binary files a/icons/png128/jaipur-hawa-mahal.png and /dev/null differ diff --git a/icons/png128/jelly-jar.png b/icons/png128/jelly-jar.png deleted file mode 100644 index 69d57620e4ebe26e349b98f6a9f2164fe113adc2..0000000000000000000000000000000000000000 Binary files a/icons/png128/jelly-jar.png and /dev/null differ diff --git a/icons/png128/journal-text.png b/icons/png128/journal-text.png deleted file mode 100644 index 28b5694af02507ed9961082a6ef4ce403e2fedee..0000000000000000000000000000000000000000 Binary files a/icons/png128/journal-text.png and /dev/null differ diff --git a/icons/png128/kebab.png b/icons/png128/kebab.png deleted file mode 100644 index 83b7a2eaca9fcbdcba90036728261fb985758851..0000000000000000000000000000000000000000 Binary files a/icons/png128/kebab.png and /dev/null differ diff --git a/icons/png128/key.png b/icons/png128/key.png deleted file mode 100644 index 7fc4363f0d61a1c315d3bcde1b9ea029b8be078b..0000000000000000000000000000000000000000 Binary files a/icons/png128/key.png and /dev/null differ diff --git a/icons/png128/knowledge-graph.png b/icons/png128/knowledge-graph.png deleted file mode 100644 index 9f403f61f5805bb50d249250ead1d584111ac311..0000000000000000000000000000000000000000 Binary files a/icons/png128/knowledge-graph.png and /dev/null differ diff --git a/icons/png128/kuala-lumpur.png b/icons/png128/kuala-lumpur.png deleted file mode 100644 index 503311d76b04bbb98bb4634b82e12dff00fc49e0..0000000000000000000000000000000000000000 Binary files a/icons/png128/kuala-lumpur.png and /dev/null differ diff --git a/icons/png128/laptop.png b/icons/png128/laptop.png deleted file mode 100644 index dc99595556463ae757ad1e2a59c94de58c2e07c6..0000000000000000000000000000000000000000 Binary files a/icons/png128/laptop.png and /dev/null differ diff --git a/icons/png128/leaning-tower-of-pisa.png b/icons/png128/leaning-tower-of-pisa.png deleted file mode 100644 index 4b5b7c8e698fd6ef7f754714e20d423cc7948c66..0000000000000000000000000000000000000000 Binary files a/icons/png128/leaning-tower-of-pisa.png and /dev/null differ diff --git a/icons/png128/lightbulb.png b/icons/png128/lightbulb.png deleted file mode 100644 index 67cb0da1182e420880cf330e92065dd17a525a41..0000000000000000000000000000000000000000 Binary files a/icons/png128/lightbulb.png and /dev/null differ diff --git a/icons/png128/lightning.png b/icons/png128/lightning.png deleted file mode 100644 index f3bdf56e510bc272345f72c57b2596a829f86991..0000000000000000000000000000000000000000 Binary files a/icons/png128/lightning.png and /dev/null differ diff --git a/icons/png128/linkedin.png b/icons/png128/linkedin.png deleted file mode 100644 index ebd0e9fc066d16bcf36ea70a515604ea1e26a794..0000000000000000000000000000000000000000 Binary files a/icons/png128/linkedin.png and /dev/null differ diff --git a/icons/png128/lock.png b/icons/png128/lock.png deleted file mode 100644 index 4820c70b1d4128ced208c04b249fd2db09a503ed..0000000000000000000000000000000000000000 Binary files a/icons/png128/lock.png and /dev/null differ diff --git a/icons/png128/london-big-ben.png b/icons/png128/london-big-ben.png deleted file mode 100644 index 7d612d6108fb77106d3d8f7903c640b83a78ff3f..0000000000000000000000000000000000000000 Binary files a/icons/png128/london-big-ben.png and /dev/null differ diff --git a/icons/png128/machine-learning.png b/icons/png128/machine-learning.png deleted file mode 100644 index c829fae5f9f32cec80b21ec0aa53bd824a0b0986..0000000000000000000000000000000000000000 Binary files a/icons/png128/machine-learning.png and /dev/null differ diff --git a/icons/png128/madrid-cathedral.png b/icons/png128/madrid-cathedral.png deleted file mode 100644 index 9b36821cd6d73d4760af1b54d5439ad943da0b81..0000000000000000000000000000000000000000 Binary files a/icons/png128/madrid-cathedral.png and /dev/null differ diff --git a/icons/png128/magic.png b/icons/png128/magic.png deleted file mode 100644 index 74a25817225223d627e5bb38e977a84a018a56b3..0000000000000000000000000000000000000000 Binary files a/icons/png128/magic.png and /dev/null differ diff --git a/icons/png128/magnet.png b/icons/png128/magnet.png deleted file mode 100644 index f3d0bdd7faf2c740cfbf7f23ee10c0626044e5e0..0000000000000000000000000000000000000000 Binary files a/icons/png128/magnet.png and /dev/null differ diff --git a/icons/png128/map.png b/icons/png128/map.png deleted file mode 100644 index 92836990f928c8921a5f4cf45ca6a398c7854db4..0000000000000000000000000000000000000000 Binary files a/icons/png128/map.png and /dev/null differ diff --git a/icons/png128/megaphone-loudspeaker.png b/icons/png128/megaphone-loudspeaker.png deleted file mode 100644 index 93c83edd9035380d3fe85cba43a21910ea738003..0000000000000000000000000000000000000000 Binary files a/icons/png128/megaphone-loudspeaker.png and /dev/null differ diff --git a/icons/png128/meta.png b/icons/png128/meta.png deleted file mode 100644 index 73fbe10ddfde1281fbabe3568a81ab68848c8ded..0000000000000000000000000000000000000000 Binary files a/icons/png128/meta.png and /dev/null differ diff --git a/icons/png128/mexico-city-angel-of-independence.png b/icons/png128/mexico-city-angel-of-independence.png deleted file mode 100644 index 2a2580453ee5348f470fb2b736b4b87fc128b78c..0000000000000000000000000000000000000000 Binary files a/icons/png128/mexico-city-angel-of-independence.png and /dev/null differ diff --git a/icons/png128/microphone.png b/icons/png128/microphone.png deleted file mode 100644 index 524c757c487db8d1fec4e524acdb058b8b51ec77..0000000000000000000000000000000000000000 Binary files a/icons/png128/microphone.png and /dev/null differ diff --git a/icons/png128/microscope.png b/icons/png128/microscope.png deleted file mode 100644 index 5eba80248556416cfc254cb99759cf52f8f28f40..0000000000000000000000000000000000000000 Binary files a/icons/png128/microscope.png and /dev/null differ diff --git a/icons/png128/microsoft.png b/icons/png128/microsoft.png deleted file mode 100644 index 664aafaa83e0323dcfd817927502217bbf279a9d..0000000000000000000000000000000000000000 Binary files a/icons/png128/microsoft.png and /dev/null differ diff --git a/icons/png128/milan-duomo-di-milano.png b/icons/png128/milan-duomo-di-milano.png deleted file mode 100644 index bd817256642733b74d6fcee74809a202576d262d..0000000000000000000000000000000000000000 Binary files a/icons/png128/milan-duomo-di-milano.png and /dev/null differ diff --git a/icons/png128/milan-skyscrapers.png b/icons/png128/milan-skyscrapers.png deleted file mode 100644 index f960c5f92b421a43f8c5e0e3e6fe0aa54887fbc6..0000000000000000000000000000000000000000 Binary files a/icons/png128/milan-skyscrapers.png and /dev/null differ diff --git a/icons/png128/mobile-smartphone.png b/icons/png128/mobile-smartphone.png deleted file mode 100644 index 6a3bcc83398fd7052c95edd1ab176bb8c63fb1ad..0000000000000000000000000000000000000000 Binary files a/icons/png128/mobile-smartphone.png and /dev/null differ diff --git a/icons/png128/modem.png b/icons/png128/modem.png deleted file mode 100644 index 936ae0e9dfe87b87999e6f6d2d2b298b64ab4692..0000000000000000000000000000000000000000 Binary files a/icons/png128/modem.png and /dev/null differ diff --git a/icons/png128/moon-stars.png b/icons/png128/moon-stars.png deleted file mode 100644 index cbbc733604911c6c4c44dc300e31a0583de36394..0000000000000000000000000000000000000000 Binary files a/icons/png128/moon-stars.png and /dev/null differ diff --git a/icons/png128/moon.png b/icons/png128/moon.png deleted file mode 100644 index 2473062487bf8034ea600d9bcca562f9c69b8170..0000000000000000000000000000000000000000 Binary files a/icons/png128/moon.png and /dev/null differ diff --git a/icons/png128/morse-code.png b/icons/png128/morse-code.png deleted file mode 100644 index 7cac330188624aa7fae7a0e7edcd1f5856a493e0..0000000000000000000000000000000000000000 Binary files a/icons/png128/morse-code.png and /dev/null differ diff --git a/icons/png128/mortarboard.png b/icons/png128/mortarboard.png deleted file mode 100644 index 7350c2a4f27745a67381f7319755e6805031b3c8..0000000000000000000000000000000000000000 Binary files a/icons/png128/mortarboard.png and /dev/null differ diff --git a/icons/png128/moscow.png b/icons/png128/moscow.png deleted file mode 100644 index 5a01bccd0ac81f39db444b117ca82e5acfe42925..0000000000000000000000000000000000000000 Binary files a/icons/png128/moscow.png and /dev/null differ diff --git a/icons/png128/motherboard.png b/icons/png128/motherboard.png deleted file mode 100644 index cb564c6ea8021c016045e00a25d6ae4d7f3e208a..0000000000000000000000000000000000000000 Binary files a/icons/png128/motherboard.png and /dev/null differ diff --git a/icons/png128/munich.png b/icons/png128/munich.png deleted file mode 100644 index 9f65422ba31fb534e16274c13bd4058cb9dc50ee..0000000000000000000000000000000000000000 Binary files a/icons/png128/munich.png and /dev/null differ diff --git a/icons/png128/music-note.png b/icons/png128/music-note.png deleted file mode 100644 index ea523976f84555ccb633fabfcb068414861d9f0f..0000000000000000000000000000000000000000 Binary files a/icons/png128/music-note.png and /dev/null differ diff --git a/icons/png128/newspaper.png b/icons/png128/newspaper.png deleted file mode 100644 index 726396b5d44eed2ec8eca0176f265931b219ac67..0000000000000000000000000000000000000000 Binary files a/icons/png128/newspaper.png and /dev/null differ diff --git a/icons/png128/no-smoking.png b/icons/png128/no-smoking.png deleted file mode 100644 index b6a310e4859353ab949c4f64bad1495c37da8450..0000000000000000000000000000000000000000 Binary files a/icons/png128/no-smoking.png and /dev/null differ diff --git a/icons/png128/noodle.png b/icons/png128/noodle.png deleted file mode 100644 index 384d532a02705fea55a1a421786f3b4640646b8b..0000000000000000000000000000000000000000 Binary files a/icons/png128/noodle.png and /dev/null differ diff --git a/icons/png128/nyc-brooklyn.png b/icons/png128/nyc-brooklyn.png deleted file mode 100644 index ca099177b52246d9b0f98f5f6876b5ff1b6d6b5b..0000000000000000000000000000000000000000 Binary files a/icons/png128/nyc-brooklyn.png and /dev/null differ diff --git a/icons/png128/nyc-statue-of-liberty.png b/icons/png128/nyc-statue-of-liberty.png deleted file mode 100644 index 7f9bf9601eadd68e4c48db14915b2905de0f364a..0000000000000000000000000000000000000000 Binary files a/icons/png128/nyc-statue-of-liberty.png and /dev/null differ diff --git a/icons/png128/nyc-world-trade-center.png b/icons/png128/nyc-world-trade-center.png deleted file mode 100644 index e8b33a81e51ae1b0a5e17a4cb993b2970c74c934..0000000000000000000000000000000000000000 Binary files a/icons/png128/nyc-world-trade-center.png and /dev/null differ diff --git a/icons/png128/oil-pump.png b/icons/png128/oil-pump.png deleted file mode 100644 index a06b24f6a912f328150d2b2e7a9887809ee3741f..0000000000000000000000000000000000000000 Binary files a/icons/png128/oil-pump.png and /dev/null differ diff --git a/icons/png128/oil-rig.png b/icons/png128/oil-rig.png deleted file mode 100644 index 4585582489f06832a7e9567020826cef426700fd..0000000000000000000000000000000000000000 Binary files a/icons/png128/oil-rig.png and /dev/null differ diff --git a/icons/png128/okinawa.png b/icons/png128/okinawa.png deleted file mode 100644 index b8b7b69c74806c902abe5aa2d7fd8fbd5b6f0027..0000000000000000000000000000000000000000 Binary files a/icons/png128/okinawa.png and /dev/null differ diff --git a/icons/png128/onigiri.png b/icons/png128/onigiri.png deleted file mode 100644 index cec89ca66d4032562287627741916e1acca9466b..0000000000000000000000000000000000000000 Binary files a/icons/png128/onigiri.png and /dev/null differ diff --git a/icons/png128/palette.png b/icons/png128/palette.png deleted file mode 100644 index a93a3914f0d50ea7f46aa3e7bfb226e1ae4b9a31..0000000000000000000000000000000000000000 Binary files a/icons/png128/palette.png and /dev/null differ diff --git a/icons/png128/pancake.png b/icons/png128/pancake.png deleted file mode 100644 index 555239fee9f4b16913b69f29da78280263389fd3..0000000000000000000000000000000000000000 Binary files a/icons/png128/pancake.png and /dev/null differ diff --git a/icons/png128/paperclip.png b/icons/png128/paperclip.png deleted file mode 100644 index ccb24a81a030a6107e34c4279d1417e550eb842d..0000000000000000000000000000000000000000 Binary files a/icons/png128/paperclip.png and /dev/null differ diff --git a/icons/png128/paris-louvre.png b/icons/png128/paris-louvre.png deleted file mode 100644 index 908a9bb1412b804cf13d1be6eeea293aaf1b48be..0000000000000000000000000000000000000000 Binary files a/icons/png128/paris-louvre.png and /dev/null differ diff --git a/icons/png128/paris-notre-dame.png b/icons/png128/paris-notre-dame.png deleted file mode 100644 index 2366b28f223e8141f3093f555ea7c9679f3dc255..0000000000000000000000000000000000000000 Binary files a/icons/png128/paris-notre-dame.png and /dev/null differ diff --git a/icons/png128/parliament.png b/icons/png128/parliament.png deleted file mode 100644 index 69c480b501dfe6ac5e92c9181991937c8d04236b..0000000000000000000000000000000000000000 Binary files a/icons/png128/parliament.png and /dev/null differ diff --git a/icons/png128/pencil.png b/icons/png128/pencil.png deleted file mode 100644 index 4ce7c96b5b7af7c4eda12b745b25aa7433411394..0000000000000000000000000000000000000000 Binary files a/icons/png128/pencil.png and /dev/null differ diff --git a/icons/png128/people.png b/icons/png128/people.png deleted file mode 100644 index ce9752024fb87a54a341611f8051616cd6689e68..0000000000000000000000000000000000000000 Binary files a/icons/png128/people.png and /dev/null differ diff --git a/icons/png128/person.png b/icons/png128/person.png deleted file mode 100644 index 3313f1d071a5a400a902f776d1e8c56e0e865929..0000000000000000000000000000000000000000 Binary files a/icons/png128/person.png and /dev/null differ diff --git a/icons/png128/peru-machu-picchu.png b/icons/png128/peru-machu-picchu.png deleted file mode 100644 index 08a779482ce59a6307590eb0eb2136b137481450..0000000000000000000000000000000000000000 Binary files a/icons/png128/peru-machu-picchu.png and /dev/null differ diff --git a/icons/png128/phone-vibrate.png b/icons/png128/phone-vibrate.png deleted file mode 100644 index 9ec0c2fc09a4e1a22385ba28b7030436a3f23620..0000000000000000000000000000000000000000 Binary files a/icons/png128/phone-vibrate.png and /dev/null differ diff --git a/icons/png128/piggy-bank.png b/icons/png128/piggy-bank.png deleted file mode 100644 index 348f34a55c9e0fa69d237c2f2a1c9c0b90e7aec5..0000000000000000000000000000000000000000 Binary files a/icons/png128/piggy-bank.png and /dev/null differ diff --git a/icons/png128/pin-angle.png b/icons/png128/pin-angle.png deleted file mode 100644 index 89a674aee883cf8cbe45d1c334bc8ab178b91d29..0000000000000000000000000000000000000000 Binary files a/icons/png128/pin-angle.png and /dev/null differ diff --git a/icons/png128/pizza.png b/icons/png128/pizza.png deleted file mode 100644 index 92124c12f3eb8032bbab3cbff4b659de8df4d85b..0000000000000000000000000000000000000000 Binary files a/icons/png128/pizza.png and /dev/null differ diff --git a/icons/png128/police.png b/icons/png128/police.png deleted file mode 100644 index 2b4603c045e3c3d264ab5098ebfab885007bc92d..0000000000000000000000000000000000000000 Binary files a/icons/png128/police.png and /dev/null differ diff --git a/icons/png128/popcorn.png b/icons/png128/popcorn.png deleted file mode 100644 index 8b37cd43efa1725e428eeb0d429e84d74d44827a..0000000000000000000000000000000000000000 Binary files a/icons/png128/popcorn.png and /dev/null differ diff --git a/icons/png128/porcelain-tower-of-nanjing.png b/icons/png128/porcelain-tower-of-nanjing.png deleted file mode 100644 index eab3198b0513657d7ffae5017db52d1437cf51fa..0000000000000000000000000000000000000000 Binary files a/icons/png128/porcelain-tower-of-nanjing.png and /dev/null differ diff --git a/icons/png128/prague-charles-bridge-tower.png b/icons/png128/prague-charles-bridge-tower.png deleted file mode 100644 index 3fcf76a86e18600e6424a557197bfca4cf22cd39..0000000000000000000000000000000000000000 Binary files a/icons/png128/prague-charles-bridge-tower.png and /dev/null differ diff --git a/icons/png128/prescription.png b/icons/png128/prescription.png deleted file mode 100644 index 3218500a7c087bc132372831d6cc6994dfde8451..0000000000000000000000000000000000000000 Binary files a/icons/png128/prescription.png and /dev/null differ diff --git a/icons/png128/printer.png b/icons/png128/printer.png deleted file mode 100644 index 3020ec364da2dc4a9545e6b58fbb91c0a47fae71..0000000000000000000000000000000000000000 Binary files a/icons/png128/printer.png and /dev/null differ diff --git a/icons/png128/pulse.png b/icons/png128/pulse.png deleted file mode 100644 index f0fdcfb64702e334d5a811d26479a5698ef2939a..0000000000000000000000000000000000000000 Binary files a/icons/png128/pulse.png and /dev/null differ diff --git a/icons/png128/python.png b/icons/png128/python.png deleted file mode 100644 index aca4bffd8fe4b75b5e0c22b1e036f074d83d6238..0000000000000000000000000000000000000000 Binary files a/icons/png128/python.png and /dev/null differ diff --git a/icons/png128/question.png b/icons/png128/question.png deleted file mode 100644 index 5f2ccb745edf187b0a8529659b53a5ae13c1dc94..0000000000000000000000000000000000000000 Binary files a/icons/png128/question.png and /dev/null differ diff --git a/icons/png128/qutb-minar.png b/icons/png128/qutb-minar.png deleted file mode 100644 index d2fc7684694da2fa86e6dc2f50d5a0f7d40762db..0000000000000000000000000000000000000000 Binary files a/icons/png128/qutb-minar.png and /dev/null differ diff --git a/icons/png128/radioactive.png b/icons/png128/radioactive.png deleted file mode 100644 index 45c4735e5398fc3a4613285a4b9c0602bbf1ae1b..0000000000000000000000000000000000000000 Binary files a/icons/png128/radioactive.png and /dev/null differ diff --git a/icons/png128/recycle.png b/icons/png128/recycle.png deleted file mode 100644 index a58dcb65195e9d78d5e88fba6d451d23ff5ce774..0000000000000000000000000000000000000000 Binary files a/icons/png128/recycle.png and /dev/null differ diff --git a/icons/png128/refinery.png b/icons/png128/refinery.png deleted file mode 100644 index 0c190388d26ce70db462f253eae3b1aba190a958..0000000000000000000000000000000000000000 Binary files a/icons/png128/refinery.png and /dev/null differ diff --git a/icons/png128/restaurant-spoon.png b/icons/png128/restaurant-spoon.png deleted file mode 100644 index 948ff3208fedc431226bb079e9810fde50c671bc..0000000000000000000000000000000000000000 Binary files a/icons/png128/restaurant-spoon.png and /dev/null differ diff --git a/icons/png128/robot-ai.png b/icons/png128/robot-ai.png deleted file mode 100644 index b3004333513d57f61aa47e3eea3da417418724fd..0000000000000000000000000000000000000000 Binary files a/icons/png128/robot-ai.png and /dev/null differ diff --git a/icons/png128/robotics.png b/icons/png128/robotics.png deleted file mode 100644 index 5d6d63d005bf665fc927f78117d5564e1acb2360..0000000000000000000000000000000000000000 Binary files a/icons/png128/robotics.png and /dev/null differ diff --git a/icons/png128/rocket-takeoff.png b/icons/png128/rocket-takeoff.png deleted file mode 100644 index f1d278a3b281d30707e1be37675976e3c08aff7a..0000000000000000000000000000000000000000 Binary files a/icons/png128/rocket-takeoff.png and /dev/null differ diff --git a/icons/png128/rome.png b/icons/png128/rome.png deleted file mode 100644 index 51cec5724a890b182781061c71bb01f6b629f981..0000000000000000000000000000000000000000 Binary files a/icons/png128/rome.png and /dev/null differ diff --git a/icons/png128/router.png b/icons/png128/router.png deleted file mode 100644 index 487bd8b068d63c5341f9c740a3ac330726b03d36..0000000000000000000000000000000000000000 Binary files a/icons/png128/router.png and /dev/null differ diff --git a/icons/png128/salad.png b/icons/png128/salad.png deleted file mode 100644 index a630aebd5f87859fa7c4997efe31bb4b4c3f4478..0000000000000000000000000000000000000000 Binary files a/icons/png128/salad.png and /dev/null differ diff --git a/icons/png128/san-francisco-fog.png b/icons/png128/san-francisco-fog.png deleted file mode 100644 index d25e96845cbc6ce297ae12d3b2d4e502d1d52780..0000000000000000000000000000000000000000 Binary files a/icons/png128/san-francisco-fog.png and /dev/null differ diff --git a/icons/png128/sandwich.png b/icons/png128/sandwich.png deleted file mode 100644 index cd8bf0bb5ea662628fc130ea41a07e5eec7236df..0000000000000000000000000000000000000000 Binary files a/icons/png128/sandwich.png and /dev/null differ diff --git a/icons/png128/sao-paulo.png b/icons/png128/sao-paulo.png deleted file mode 100644 index ae46ce9fb250e87fff02da1611730d9388108bb5..0000000000000000000000000000000000000000 Binary files a/icons/png128/sao-paulo.png and /dev/null differ diff --git a/icons/png128/satellite.png b/icons/png128/satellite.png deleted file mode 100644 index 04cfea2be79f245f1554fa9924a3c4c10cbdbc8a..0000000000000000000000000000000000000000 Binary files a/icons/png128/satellite.png and /dev/null differ diff --git a/icons/png128/scissors.png b/icons/png128/scissors.png deleted file mode 100644 index e05d3690d139877aa0b004387453022059bb10af..0000000000000000000000000000000000000000 Binary files a/icons/png128/scissors.png and /dev/null differ diff --git a/icons/png128/screwdriver.png b/icons/png128/screwdriver.png deleted file mode 100644 index dcbc2ac21abcc02ca640e63c30b3685d784894ae..0000000000000000000000000000000000000000 Binary files a/icons/png128/screwdriver.png and /dev/null differ diff --git a/icons/png128/search.png b/icons/png128/search.png deleted file mode 100644 index 06b38ff04765800da3ec9e9051c84cfaafd2ce27..0000000000000000000000000000000000000000 Binary files a/icons/png128/search.png and /dev/null differ diff --git a/icons/png128/seattle.png b/icons/png128/seattle.png deleted file mode 100644 index 4321a073350f60588f66640cd8fb33c4bdfc006e..0000000000000000000000000000000000000000 Binary files a/icons/png128/seattle.png and /dev/null differ diff --git a/icons/png128/shield-check.png b/icons/png128/shield-check.png deleted file mode 100644 index 1a0bf290e171a9e030277319dc8127cb7c2b8958..0000000000000000000000000000000000000000 Binary files a/icons/png128/shield-check.png and /dev/null differ diff --git a/icons/png128/shuffle.png b/icons/png128/shuffle.png deleted file mode 100644 index d68889f604be26827bfa781d32a1d4e49231fc41..0000000000000000000000000000000000000000 Binary files a/icons/png128/shuffle.png and /dev/null differ diff --git a/icons/png128/singapore.png b/icons/png128/singapore.png deleted file mode 100644 index 5d56e87a78e696293a0d87bada65d174231b4269..0000000000000000000000000000000000000000 Binary files a/icons/png128/singapore.png and /dev/null differ diff --git a/icons/png128/solar-panel.png b/icons/png128/solar-panel.png deleted file mode 100644 index 9ef6a6c41cdd0541fe551932315375dae66252e2..0000000000000000000000000000000000000000 Binary files a/icons/png128/solar-panel.png and /dev/null differ diff --git a/icons/png128/soundwave.png b/icons/png128/soundwave.png deleted file mode 100644 index e0acedc6406e8086daf92165561a92415fad63a5..0000000000000000000000000000000000000000 Binary files a/icons/png128/soundwave.png and /dev/null differ diff --git a/icons/png128/speedometer.png b/icons/png128/speedometer.png deleted file mode 100644 index a327a92c4871b3dd71905f9853487a3260f3908a..0000000000000000000000000000000000000000 Binary files a/icons/png128/speedometer.png and /dev/null differ diff --git a/icons/png128/sphinx-monuments.png b/icons/png128/sphinx-monuments.png deleted file mode 100644 index 1f19832ac973cc1a326ce91dbb05143c8f8e2b26..0000000000000000000000000000000000000000 Binary files a/icons/png128/sphinx-monuments.png and /dev/null differ diff --git a/icons/png128/stars.png b/icons/png128/stars.png deleted file mode 100644 index 37f7c0cb4ce973011a9d8b87a73fe03bf90f83c1..0000000000000000000000000000000000000000 Binary files a/icons/png128/stars.png and /dev/null differ diff --git a/icons/png128/stethoscope.png b/icons/png128/stethoscope.png deleted file mode 100644 index 73cb2a7b9036efb80b226add18f2444ef76b11b6..0000000000000000000000000000000000000000 Binary files a/icons/png128/stethoscope.png and /dev/null differ diff --git a/icons/png128/stockholm.png b/icons/png128/stockholm.png deleted file mode 100644 index 52cc42d5ec5b2668f14b09c44e31fc99b195ef95..0000000000000000000000000000000000000000 Binary files a/icons/png128/stockholm.png and /dev/null differ diff --git a/icons/png128/strategy.png b/icons/png128/strategy.png deleted file mode 100644 index 5007a5f2ffc0524556153dfd7d367888d35d71ed..0000000000000000000000000000000000000000 Binary files a/icons/png128/strategy.png and /dev/null differ diff --git a/icons/png128/suitcase.png b/icons/png128/suitcase.png deleted file mode 100644 index e11d11b827cd3b9c435654b507ef97a0ad9ff484..0000000000000000000000000000000000000000 Binary files a/icons/png128/suitcase.png and /dev/null differ diff --git a/icons/png128/sushi.png b/icons/png128/sushi.png deleted file mode 100644 index ea339e20e7e3cfa370231891552fef8f9e3fd323..0000000000000000000000000000000000000000 Binary files a/icons/png128/sushi.png and /dev/null differ diff --git a/icons/png128/sydney-opera-house.png b/icons/png128/sydney-opera-house.png deleted file mode 100644 index d97c03c09779e59933fcd31815c7abbeaa523c5c..0000000000000000000000000000000000000000 Binary files a/icons/png128/sydney-opera-house.png and /dev/null differ diff --git a/icons/png128/table.png b/icons/png128/table.png deleted file mode 100644 index ddfa856f016a52e169b465d364534c407505bd46..0000000000000000000000000000000000000000 Binary files a/icons/png128/table.png and /dev/null differ diff --git a/icons/png128/taj-mahal.png b/icons/png128/taj-mahal.png deleted file mode 100644 index 108d587d6dd16f977c02a1c97eb41addaa943bca..0000000000000000000000000000000000000000 Binary files a/icons/png128/taj-mahal.png and /dev/null differ diff --git a/icons/png128/tap-hands-and-gestures.png b/icons/png128/tap-hands-and-gestures.png deleted file mode 100644 index 291c798213d0aa328a2c03c4902b877ec3008c3a..0000000000000000000000000000000000000000 Binary files a/icons/png128/tap-hands-and-gestures.png and /dev/null differ diff --git a/icons/png128/taxi-front.png b/icons/png128/taxi-front.png deleted file mode 100644 index 1f004b6af047d27a01c6cbf0cb27db68a94fcffc..0000000000000000000000000000000000000000 Binary files a/icons/png128/taxi-front.png and /dev/null differ diff --git a/icons/png128/tea-coffee-cup.png b/icons/png128/tea-coffee-cup.png deleted file mode 100644 index 4d556d4c53c33aaba8200d7f43477fce9dcfdb35..0000000000000000000000000000000000000000 Binary files a/icons/png128/tea-coffee-cup.png and /dev/null differ diff --git a/icons/png128/telemarketer-customer-service.png b/icons/png128/telemarketer-customer-service.png deleted file mode 100644 index f642b2f9606007b9dd31e870ae30fc046fae32cd..0000000000000000000000000000000000000000 Binary files a/icons/png128/telemarketer-customer-service.png and /dev/null differ diff --git a/icons/png128/telephone.png b/icons/png128/telephone.png deleted file mode 100644 index c55987a503e002eea6306801b43786a974d4e83a..0000000000000000000000000000000000000000 Binary files a/icons/png128/telephone.png and /dev/null differ diff --git a/icons/png128/temple-of-heaven-in-beijing.png b/icons/png128/temple-of-heaven-in-beijing.png deleted file mode 100644 index cb218c18430e619a77bf22c51190efb6e2b1ecd0..0000000000000000000000000000000000000000 Binary files a/icons/png128/temple-of-heaven-in-beijing.png and /dev/null differ diff --git a/icons/png128/teotihuacan-aztec.png b/icons/png128/teotihuacan-aztec.png deleted file mode 100644 index 5f1b063a5fe8b6df93a283a49af58ed008bd1f70..0000000000000000000000000000000000000000 Binary files a/icons/png128/teotihuacan-aztec.png and /dev/null differ diff --git a/icons/png128/thermometer.png b/icons/png128/thermometer.png deleted file mode 100644 index 7262a72551fb2fd93d1adf6774c962d51dbb2615..0000000000000000000000000000000000000000 Binary files a/icons/png128/thermometer.png and /dev/null differ diff --git a/icons/png128/tokyo-gates.png b/icons/png128/tokyo-gates.png deleted file mode 100644 index bc3c419b4c7687e5303960132214a184a6a65a73..0000000000000000000000000000000000000000 Binary files a/icons/png128/tokyo-gates.png and /dev/null differ diff --git a/icons/png128/tokyo-temple.png b/icons/png128/tokyo-temple.png deleted file mode 100644 index 9ba6ad07b9f1ec063349d59743595909a3913a39..0000000000000000000000000000000000000000 Binary files a/icons/png128/tokyo-temple.png and /dev/null differ diff --git a/icons/png128/tools.png b/icons/png128/tools.png deleted file mode 100644 index 5b1ddef6f8284a855832ea51e065dc7bdb2dcd61..0000000000000000000000000000000000000000 Binary files a/icons/png128/tools.png and /dev/null differ diff --git a/icons/png128/toronto.png b/icons/png128/toronto.png deleted file mode 100644 index a0af687062b9c5a52f63d7055bca225cf4b1bacc..0000000000000000000000000000000000000000 Binary files a/icons/png128/toronto.png and /dev/null differ diff --git a/icons/png128/translate.png b/icons/png128/translate.png deleted file mode 100644 index 90d06bb7243ff78373c1671ac09f88373dd9592b..0000000000000000000000000000000000000000 Binary files a/icons/png128/translate.png and /dev/null differ diff --git a/icons/png128/trash.png b/icons/png128/trash.png deleted file mode 100644 index 7d9d4b7a84d192006fbce7f1932edb4bd1d4175c..0000000000000000000000000000000000000000 Binary files a/icons/png128/trash.png and /dev/null differ diff --git a/icons/png128/trophy.png b/icons/png128/trophy.png deleted file mode 100644 index 977999fcd705cd2c4138d9670f70b2180a19eae9..0000000000000000000000000000000000000000 Binary files a/icons/png128/trophy.png and /dev/null differ diff --git a/icons/png128/truck.png b/icons/png128/truck.png deleted file mode 100644 index 7feaae299507dcd93b591e8c610ff76dda2f2d92..0000000000000000000000000000000000000000 Binary files a/icons/png128/truck.png and /dev/null differ diff --git a/icons/png128/txt.png b/icons/png128/txt.png deleted file mode 100644 index 2ba563a3ed81a7ce3ec577b3a0a56d70776ec62f..0000000000000000000000000000000000000000 Binary files a/icons/png128/txt.png and /dev/null differ diff --git a/icons/png128/ubuntu.png b/icons/png128/ubuntu.png deleted file mode 100644 index a11e3fe7de6cbf0f1faa5ca793fafc0c95bb044b..0000000000000000000000000000000000000000 Binary files a/icons/png128/ubuntu.png and /dev/null differ diff --git a/icons/png128/umbrella.png b/icons/png128/umbrella.png deleted file mode 100644 index 237f1a506e07a608e3ca0d6ce9cc7d896e585150..0000000000000000000000000000000000000000 Binary files a/icons/png128/umbrella.png and /dev/null differ diff --git a/icons/png128/unlock.png b/icons/png128/unlock.png deleted file mode 100644 index 82c4e002e8be13f4d882135f5669ec995aab416f..0000000000000000000000000000000000000000 Binary files a/icons/png128/unlock.png and /dev/null differ diff --git a/icons/png128/value.png b/icons/png128/value.png deleted file mode 100644 index ffd63872110a36a61dad48b9399d7a623b54d24a..0000000000000000000000000000000000000000 Binary files a/icons/png128/value.png and /dev/null differ diff --git a/icons/png128/venezuela-national-pantheon-of-venezuela.png b/icons/png128/venezuela-national-pantheon-of-venezuela.png deleted file mode 100644 index f7856d3b35024485f530b5b759be46139538d8eb..0000000000000000000000000000000000000000 Binary files a/icons/png128/venezuela-national-pantheon-of-venezuela.png and /dev/null differ diff --git a/icons/png128/virus.png b/icons/png128/virus.png deleted file mode 100644 index 41aabbac30e4c562ddf3559682363e166266b1d8..0000000000000000000000000000000000000000 Binary files a/icons/png128/virus.png and /dev/null differ diff --git a/icons/png128/wallet.png b/icons/png128/wallet.png deleted file mode 100644 index fb86ac6153d0977a163a6e1db83ea7781ca72622..0000000000000000000000000000000000000000 Binary files a/icons/png128/wallet.png and /dev/null differ diff --git a/icons/png128/warehouse.png b/icons/png128/warehouse.png deleted file mode 100644 index 86717e680c0aefd5ab00d858e676e64bdf855c64..0000000000000000000000000000000000000000 Binary files a/icons/png128/warehouse.png and /dev/null differ diff --git a/icons/png128/washington-dc-capitol.png b/icons/png128/washington-dc-capitol.png deleted file mode 100644 index 242d8eb37f069229644f80ef9b5cc2d0ed63e3be..0000000000000000000000000000000000000000 Binary files a/icons/png128/washington-dc-capitol.png and /dev/null differ diff --git a/icons/png128/washington-dc-monument.png b/icons/png128/washington-dc-monument.png deleted file mode 100644 index 0e1d0c4c4c971fbe5f5d9d8c85c8dfbed9726e74..0000000000000000000000000000000000000000 Binary files a/icons/png128/washington-dc-monument.png and /dev/null differ diff --git a/icons/png128/watch.png b/icons/png128/watch.png deleted file mode 100644 index 83ecca8525ebad409f4b4f58ab88bbe621138548..0000000000000000000000000000000000000000 Binary files a/icons/png128/watch.png and /dev/null differ diff --git a/icons/png128/webcam-video-chat.png b/icons/png128/webcam-video-chat.png deleted file mode 100644 index c2c6e5993aa5573e8affa58f28a096d4c11400c7..0000000000000000000000000000000000000000 Binary files a/icons/png128/webcam-video-chat.png and /dev/null differ diff --git a/icons/png128/whatsapp.png b/icons/png128/whatsapp.png deleted file mode 100644 index 9e716445445aded018a652326a7fa3bf5563ba84..0000000000000000000000000000000000000000 Binary files a/icons/png128/whatsapp.png and /dev/null differ diff --git a/icons/png128/wifi.png b/icons/png128/wifi.png deleted file mode 100644 index 7d5f01c0b66034880bed05f07095c64c3b140d94..0000000000000000000000000000000000000000 Binary files a/icons/png128/wifi.png and /dev/null differ diff --git a/icons/png128/windmill.png b/icons/png128/windmill.png deleted file mode 100644 index 9bd981eea0730a9d2be83cdcfdea1b7ad59d3d2a..0000000000000000000000000000000000000000 Binary files a/icons/png128/windmill.png and /dev/null differ diff --git a/icons/png128/wrecking-ball.png b/icons/png128/wrecking-ball.png deleted file mode 100644 index b202696aa4c67f6b0c6c23c72b7eba1d44b71c16..0000000000000000000000000000000000000000 Binary files a/icons/png128/wrecking-ball.png and /dev/null differ diff --git a/icons/png128/xml.png b/icons/png128/xml.png deleted file mode 100644 index d842f4084d9d7c3a6b4b62f08ec88b78ab9c4ebe..0000000000000000000000000000000000000000 Binary files a/icons/png128/xml.png and /dev/null differ diff --git a/icons/png128/yin-yang.png b/icons/png128/yin-yang.png deleted file mode 100644 index 61a4405d1d0e12a4a726d236c7a8738dbbe74bd3..0000000000000000000000000000000000000000 Binary files a/icons/png128/yin-yang.png and /dev/null differ diff --git a/icons/png128/yml.png b/icons/png128/yml.png deleted file mode 100644 index 51a68d499de753aa9c824fe5514c45b3f84fa54f..0000000000000000000000000000000000000000 Binary files a/icons/png128/yml.png and /dev/null differ diff --git a/icons/png128/youtube.png b/icons/png128/youtube.png deleted file mode 100644 index 3f1a8f4ddb1ae08123f04630738ec485a709489d..0000000000000000000000000000000000000000 Binary files a/icons/png128/youtube.png and /dev/null differ diff --git a/icons/svg_repo.txt b/icons/svg_repo.txt deleted file mode 100644 index ebf00206ab92b3576a7820e00b9310e248d61b75..0000000000000000000000000000000000000000 --- a/icons/svg_repo.txt +++ /dev/null @@ -1,176 +0,0 @@ -Icons collections used (and their licenses) from SVG Repo: -- Basicons Interface Line Icons Collection (MIT License): https://www.svgrepo.com/collection/basicons-interface-line-icons/ -- Big Data And Web Analytics (CC0 License): https://www.svgrepo.com/collection/big-data-and-web-analytics/ -- Calcite Sharp Line Icons Collection (MIT License): https://www.svgrepo.com/collection/calcite-sharp-line-icons/ -- Carbon Design Pictograms (Apache License): https://www.svgrepo.com/collection/carbon-design-pictograms/ -- Communication 71 Collection (CC0 License): https://www.svgrepo.com/collection/communication-71/ -- Denali Solid Interface Icons Collection (MIT License): https://www.svgrepo.com/collection/denali-solid-interface-icons/ -- Fast Food Junk Line Vectors Collection (CC0 License): https://www.svgrepo.com/collection/fast-food-junk-line-vectors/ -- Flexicon Sharp Interface Glyphs (MIT License): https://www.svgrepo.com/collection/flexicon-sharp-interface-glyphs/ -- Future Technology 2 (CC0 License): https://www.svgrepo.com/collection/future-technology-2/ -- Linear Monuments Collection (CC0 License): https://www.svgrepo.com/collection/linear-monuments/ -- Monuments 1 Collection (CC0 License): https://www.svgrepo.com/collection/monuments-1/ -- Monuments 3 Collection (CC0 License): https://www.svgrepo.com/collection/monuments-3/ -- Monuments 5 Collection (CC0 License): https://www.svgrepo.com/collection/monuments-5/ -- Monuments 9 Collection (CC0 License): https://www.svgrepo.com/collection/monuments-9/ -- Network 7 (CC0 License): https://www.svgrepo.com/collection/network-7/ -- Objects Infographic Icons (CC0 License): https://www.svgrepo.com/collection/objects-infographic-icons/ -- Scientifics Study Collection (CC0 License): https://www.svgrepo.com/collection/scientifics-study/ -- Thanksgiving 4 Collection (CC0 License): https://www.svgrepo.com/collection/thanksgiving-4/ -- Using Hands Collection (CC0 License): https://www.svgrepo.com/collection/using-hands/ -- Vaadin Flat Vectors Collection (Apache License): https://www.svgrepo.com/collection/vaadin-flat-vectors/ - -- India ICON SET (SVG) [NO attribution required]: https://icon666.com/collection/india_m7tgpnohh - - -The specific icons used are: -https://www.svgrepo.com/download/235147/artificial-intelligence.svg -https://www.svgrepo.com/download/235194/windmill.svg -https://www.svgrepo.com/download/235161/robot-ai.svg -https://www.svgrepo.com/download/235166/industrial-robot.svg -https://www.svgrepo.com/download/235170/drone.svg -https://www.svgrepo.com/download/235189/solar-panel.svg -https://www.svgrepo.com/download/235191/graphene-carbon.svg -https://www.svgrepo.com/download/235192/tap-hands-and-gestures.svg -https://www.svgrepo.com/download/506680/smartphone.svg -https://www.svgrepo.com/download/259945/router.svg -https://www.svgrepo.com/download/299210/warehouse.svg -https://www.svgrepo.com/download/299178/value.svg -https://www.svgrepo.com/download/299170/data-document.svg -https://www.svgrepo.com/download/339330/machine-learning-03.svg -https://www.svgrepo.com/download/450794/deep-learning.svg -https://www.svgrepo.com/download/450704/certificate.svg -https://www.svgrepo.com/download/451006/knowledge-graph.svg -https://www.svgrepo.com/download/451276/satellite-3.svg -https://www.svgrepo.com/download/32364/glasses.svg -https://www.svgrepo.com/download/42246/gloves.svg -https://www.svgrepo.com/download/127799/alien-head.svg -https://www.svgrepo.com/download/128855/pulse.svg -https://www.svgrepo.com/download/156615/brain.svg -https://www.svgrepo.com/download/108458/cardiogram.svg -https://www.svgrepo.com/download/7010/microscope.svg -https://www.svgrepo.com/download/5170/flask.svg -https://www.svgrepo.com/download/445375/stethoscope-solid.svg -https://www.svgrepo.com/download/286233/laptop.svg -https://www.svgrepo.com/download/286239/computer-tv.svg -https://www.svgrepo.com/download/286242/conversation.svg -https://www.svgrepo.com/download/286250/megaphone-loudspeaker.svg -https://www.svgrepo.com/download/286262/webcam-video-chat.svg -https://www.svgrepo.com/download/286243/microphone.svg -https://www.svgrepo.com/download/286283/morse-code.svg -https://www.svgrepo.com/download/286275/telemarketer-customer-service.svg -https://www.svgrepo.com/download/339144/doctor-patient.svg -https://www.svgrepo.com/download/339182/eye.svg -https://www.svgrepo.com/download/339203/finance-strategy.svg -https://www.svgrepo.com/download/339434/police.svg -https://www.svgrepo.com/download/339442/prescription.svg -https://www.svgrepo.com/download/339484/robotics.svg -https://www.svgrepo.com/download/339552/strategy.svg -https://www.svgrepo.com/download/339032/chart-t-sne.svg -https://www.svgrepo.com/download/339141/dna.svg -https://www.svgrepo.com/download/339194/farmer-02.svg -https://www.svgrepo.com/download/371555/stethoscope.svg -/339608/tokyo-temple.svg -https://www.svgrepo.com/download/339736/automation-decision.svg -https://www.svgrepo.com/download/339734/austin.svg -https://www.svgrepo.com/download/339733/atlanta.svg -https://www.svgrepo.com/download/339726/argentina-obelisk.svg -https://www.svgrepo.com/download/339718/amsterdam-windmill.svg -https://www.svgrepo.com/download/339715/amsterdam-canal.svg -https://www.svgrepo.com/download/339687/wrecking-ball.svg -https://www.svgrepo.com/download/339670/washington-dc-monument.svg -https://www.svgrepo.com/download/339669/washington-dc-capitol.svg -https://www.svgrepo.com/download/339655/venezuela-national-pantheon-of-venezuela.svg -https://www.svgrepo.com/download/339607/tokyo-gates.svg -https://www.svgrepo.com/download/339615/toronto.svg -https://www.svgrepo.com/download/339549/stockholm.svg -https://www.svgrepo.com/download/339519/singapore.svg -https://www.svgrepo.com/download/339501/seattle.svg -https://www.svgrepo.com/download/339494/san-francisco-fog.svg -https://www.svgrepo.com/download/339493/sao-paulo.svg -https://www.svgrepo.com/download/339489/rome.svg -https://www.svgrepo.com/download/339468/refinery.svg -https://www.svgrepo.com/download/339438/prague-charles-bridge-tower.svg -https://www.svgrepo.com/download/339425/peru-machu-picchu.svg -https://www.svgrepo.com/download/339390/nyc-brooklyn.svg -https://www.svgrepo.com/download/339391/no-smoking.svg -https://www.svgrepo.com/download/339407/paris-notre-dame.svg -https://www.svgrepo.com/download/339408/paris-louvre.svg -https://www.svgrepo.com/download/339412/parliament.svg -https://www.svgrepo.com/download/339399/okinawa.svg -https://www.svgrepo.com/download/339398/oil-rig.svg -https://www.svgrepo.com/download/339397/oil-pump.svg -https://www.svgrepo.com/download/339396/nyc-world-trade-center.svg -https://www.svgrepo.com/download/339394/nyc-statue-of-liberty.svg -https://www.svgrepo.com/download/339375/munich.svg -https://www.svgrepo.com/download/339337/madrid-cathedral.svg -https://www.svgrepo.com/download/339367/moscow.svg -https://www.svgrepo.com/download/339357/milan-skyscrapers.svg -https://www.svgrepo.com/download/339351/mexico-city-angel-of-independence.svg -https://www.svgrepo.com/download/339356/milan-duomo-di-milano.svg -https://www.svgrepo.com/download/339324/london-big-ben.svg -https://www.svgrepo.com/download/339307/kuala-lumpur.svg -https://www.svgrepo.com/download/339272/hospital.svg -https://www.svgrepo.com/download/339269/hong-kong.svg -https://www.svgrepo.com/download/339190/fairness.svg -https://www.svgrepo.com/download/339175/escalator-up.svg -https://www.svgrepo.com/download/339159/ecuador-quito.svg -https://www.svgrepo.com/download/339156/dublin-castle.svg -https://www.svgrepo.com/download/339004/capitol.svg -https://www.svgrepo.com/download/338997/cafe.svg -https://www.svgrepo.com/download/338988/budapest.svg -https://www.svgrepo.com/download/338985/blockchain.svg -https://www.svgrepo.com/download/338984/boston-zakim-bridge.svg -https://www.svgrepo.com/download/338981/berlin-tower.svg -https://www.svgrepo.com/download/338980/beijing-tower.svg -https://www.svgrepo.com/download/338977/berlin-cathedral.svg -https://www.svgrepo.com/download/338976/beijing-municipal.svg -https://www.svgrepo.com/download/338974/barcelona.svg -https://www.svgrepo.com/download/338971/bangalore.svg -https://www.svgrepo.com/download/339734/austin.svg -https://www.svgrepo.com/download/338998/cairo-giza-plateau.svg -https://www.svgrepo.com/download/179037/sphinx-monuments.svg -https://www.svgrepo.com/download/179023/eiffel-tower-travel.svg -https://www.svgrepo.com/download/175156/temple-of-heaven-in-beijing.svg -https://www.svgrepo.com/download/103185/porcelain-tower-of-nanjing.svg -https://www.svgrepo.com/download/80664/taj-mahal.svg -https://www.svgrepo.com/download/127582/sydney-opera-house.svg -https://www.svgrepo.com/download/170194/christ-the-redeemer.svg -https://www.svgrepo.com/download/196713/hassan-mosque-morocco.svg -https://www.svgrepo.com/download/196708/teotihuacan-aztec.svg -https://www.svgrepo.com/download/196712/great-buddha-of-thailand-thailand.svg -https://www.svgrepo.com/download/196714/great-wall-of-china.svg -https://www.svgrepo.com/download/196715/gate-of-india-mumbai.svg -https://www.svgrepo.com/download/14517/qutb-minar.svg - -https://icon666.com/icon/red_fort_qyg7rbqgqywb -https://icon666.com/icon/jantar_mantar_kbo0wk1dah7i -https://icon666.com/icon/jama_masjid_uxb6glpbcomj -https://icon666.com/icon/humayun_31si8fr6ow6n -https://icon666.com/icon/hawa_mahal_puga89z201h8 -https://icon666.com/icon/golden_temple_iqso963j6mn1 -https://icon666.com/icon/ganges_72fztx3tpikg -https://icon666.com/icon/lotus_temple_uz2oct12rka4 - -https://www.svgrepo.com/download/423081/fast-food-steak.svg -https://www.svgrepo.com/download/423101/fast-food-kebab.svg -https://www.svgrepo.com/download/423102/fast-food-sandwich.svg -https://www.svgrepo.com/download/423103/fast-food-salad.svg -https://www.svgrepo.com/download/423104/fast-food-popcorn.svg -https://www.svgrepo.com/download/423100/fast-food-burger.svg -https://www.svgrepo.com/download/423099/fast-food-pancake.svg -https://www.svgrepo.com/download/423096/fast-food-pudding.svg -https://www.svgrepo.com/download/423095/fast-food-onigiri.svg -https://www.svgrepo.com/download/423092/fast-food-donut.svg -https://www.svgrepo.com/download/423091/fast-food-bread.svg -https://www.svgrepo.com/download/423090/fast-food-pizza.svg -https://www.svgrepo.com/download/423087/fast-food-noodle.svg -https://www.svgrepo.com/download/423086/fast-food-ice.svg -https://www.svgrepo.com/download/423085/fast-food-french.svg -https://www.svgrepo.com/download/423084/fast-food-hotdog.svg -https://www.svgrepo.com/download/423083/fast-food-sushi.svg -https://www.svgrepo.com/download/423082/fast-food-fried-2.svg -https://www.svgrepo.com/download/209887/tea-coffee-cup.svg -https://www.svgrepo.com/download/209855/restaurant-spoon.svg -https://www.svgrepo.com/download/209875/jelly-jar.svg -https://www.svgrepo.com/download/83723/handshake.svg diff --git a/langchain_templates/chat_prompts/initial_template.txt b/langchain_templates/chat_prompts/initial_template.txt deleted file mode 100644 index 1db95a04046a0fd26ea9b517dd678a669530245f..0000000000000000000000000000000000000000 --- a/langchain_templates/chat_prompts/initial_template.txt +++ /dev/null @@ -1,41 +0,0 @@ -You are a helpful, intelligent chatbot. Create the slides for a presentation on the given topic. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant content to each slide. -The content of each slide should be verbose, descriptive, and very detailed. -If relevant, add one or two examples to illustrate the concept. -Unless explicitly specified with the topic, create about 10 slides. - - -### Topic: -{question} - - -The output must be only a valid and syntactically correct JSON adhering to the following schema: -{{ - "title": "Presentation Title", - "slides": [ - {{ - "heading": "Heading for the First Slide", - "bullet_points": [ - "First bullet point", - [ - "Sub-bullet point 1", - "Sub-bullet point 2" - ], - "Second bullet point" - ] - }}, - {{ - "heading": "Heading for the Second Slide", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }} - ] -}} - - -### Output: -```json \ No newline at end of file diff --git a/langchain_templates/chat_prompts/initial_template_v2_steps.txt b/langchain_templates/chat_prompts/initial_template_v2_steps.txt deleted file mode 100644 index 7df8ebcf377bd45eae9b01337c092148c5b930a9..0000000000000000000000000000000000000000 --- a/langchain_templates/chat_prompts/initial_template_v2_steps.txt +++ /dev/null @@ -1,59 +0,0 @@ -You are a helpful, intelligent chatbot. Create the slides for a presentation on the given topic. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant content to each slide. -The content of each slide should be verbose, descriptive, and very detailed. -If relevant, add one or two examples to illustrate the concept. -Unless explicitly specified with the topic, create about 10 slides. - - -### Topic: -{question} - - -The output must be only a valid and syntactically correct JSON adhering to the following schema: -{{ - "title": "Presentation Title", - "slides": [ - {{ - "heading": "Heading for the First Slide", - "bullet_points": [ - "First bullet point", - [ - "Sub-bullet point 1", - "Sub-bullet point 2" - ], - "Second bullet point" - ], - "key_message": "" - }}, - {{ - "heading": "Heading for the Second Slide", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ], - "key_message": "The key message conveyed in this slide" - }}, - {{ - "heading": "A slide that describes a step-by-step/sequential process", - "bullet_points": [ - ">> The first step of the process (begins with special marker >>)", - ">> A second step (begins with >>)", - ">> Third step", - ], - "key_message": "" - }} - ] -}} - - -### Some more hints on the slide content and JSON output format: -- For two or three important slides, generate the key message that those slides convey and assign -them to the `key_message` elements of JSON output. -- Identify if a slide describes a step-by-step/sequential process, then begin the bullet points -with a special marker >>. Limit this to max two or three slides. - - -### Output: -```json \ No newline at end of file diff --git a/langchain_templates/chat_prompts/initial_template_v3_two_cols.txt b/langchain_templates/chat_prompts/initial_template_v3_two_cols.txt deleted file mode 100644 index 0df280ad9d13086ff443795883679d917a0a3b22..0000000000000000000000000000000000000000 --- a/langchain_templates/chat_prompts/initial_template_v3_two_cols.txt +++ /dev/null @@ -1,78 +0,0 @@ -You are a helpful, intelligent chatbot. Create the slides for a presentation on the given topic. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant content to each slide. -The content of each slide should be VERBOSE, DESCRIPTIVE, and very DETAILED. -If relevant, add one or two EXAMPLES to illustrate the concept. -For two or three important slides, generate the key message that those slides convey. -Identify if a slide describes a step-by-step/sequential process, then begin the bullet points with a special marker >>. Limit this to max two or three slides. -Also, add at least one slide with a double column layout by generating appropriate content based on the description in the JSON schema provided below. -ALWAYS add a concluding slide at the end, containing a list of the key takeways and an optional call-to-action if relevant to the context. -Unless explicitly instructed, create 10 TO 12 SLIDES in total. - - -### Topic: -{question} - - -The output must be only a valid and syntactically correct JSON adhering to the following schema: -{{ - "title": "Presentation Title", - "slides": [ - {{ - "heading": "Heading for the First Slide", - "bullet_points": [ - "First bullet point", - [ - "Sub-bullet point 1", - "Sub-bullet point 2" - ], - "Second bullet point" - ], - "key_message": "" - }}, - {{ - "heading": "Heading for the Second Slide", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ], - "key_message": "The key message conveyed in this slide" - }}, - {{ - "heading": "A slide that describes a step-by-step/sequential process", - "bullet_points": [ - ">> The first step of the process (begins with special marker >>)", - ">> A second step (begins with >>)", - ">> Third step", - ], - "key_message": "" - }}, - {{ - "heading": "A slide with a double column layout (useful for side-by-side comparison/contrasting of two related concepts, e.g., pros & cons, advantages & risks, old approach vs. modern approach, and so on)", - "bullet_points": [ - {{ - "heading": "Heading of the left column", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }}, - {{ - "heading": "Heading of the right column", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }} - ], - "key_message": "" - }} - ] -}} - - -### Output: -```json \ No newline at end of file diff --git a/langchain_templates/chat_prompts/initial_template_v4_two_cols_img.txt b/langchain_templates/chat_prompts/initial_template_v4_two_cols_img.txt deleted file mode 100644 index a6d68e7be6a74312514c2c39c1b2a02bd3cd7961..0000000000000000000000000000000000000000 --- a/langchain_templates/chat_prompts/initial_template_v4_two_cols_img.txt +++ /dev/null @@ -1,109 +0,0 @@ -You are a helpful, intelligent assistant. You are experienced with PowerPoint. - -Create the slides for a presentation on the given topic. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant, detailed content to each slide. When relevant, add one or two EXAMPLES to illustrate the concept. -For two or three important slides, generate the key message that those slides convey. - -Identify if a slide describes a step-by-step/sequential process, then begin the bullet points with a special marker >>. -Limit this to max two or three slides. - -Also, add at least one slide with a double column layout by generating appropriate content based on the description in the JSON schema provided below. -In addition, for each slide, add image keywords based on the content of the respective slides. -These keywords will be later used to search for images from the Web relevant to the slide content. - -In addition, create one slide containing 4 TO 6 icons (pictograms) illustrating some key ideas/aspects/concepts relevant to the topic. -In this slide, each line of text will begin with the name of a relevant icon enclosed between [[ and ]]. -Select appropriate and exact icon names from the section provided below. - - -{icons_list} - - -The content of each slide should be VERBOSE, DESCRIPTIVE, and very DETAILED. Each bullet point should be detailed and explanatory, not just short phrases. - -ALWAYS add a concluding slide at the end, containing a list of the key takeaways and an optional call-to-action if relevant to the context. -Unless explicitly instructed with the topic, create 10 TO 12 SLIDES in total. You must never create more tha 15 slides. - - -### Topic: -{question} - - -The output must be only a valid and syntactically correct JSON adhering to the following schema: -{{ - "title": "Presentation Title", - "slides": [ - {{ - "heading": "Heading for the First Slide", - "bullet_points": [ - "First bullet point", - [ - "Sub-bullet point 1", - "Sub-bullet point 2" - ], - "Second bullet point" - ], - "key_message": "", - "img_keywords": "a few keywords" - }}, - {{ - "heading": "Heading for the Second Slide", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ], - "key_message": "The key message conveyed in this slide", - "img_keywords": "some keywords for this slide" - }}, - {{ - "heading": "A slide illustrating key ideas/aspects/concepts (Hint: generate an appropriate heading)", - "bullet_points": [ - "[[icon name]] Some text", - "[[another icon name]] Some words describing this aspect", - "[[icon]] Another aspect highlighted here", - "[[an icon]] Another point here", - ], - "key_message": "", - "img_keywords": "" - }}, - {{ - "heading": "A slide that describes a step-by-step/sequential process", - "bullet_points": [ - ">> The first step of the process (begins with special marker >>)", - ">> A second step (begins with >>)", - ">> Third step", - ], - "key_message": "", - "img_keywords": "" - }}, - {{ - "heading": "A slide with a double column layout (useful for side-by-side comparison/contrasting of two related concepts, e.g., pros & cons, advantages & risks, old approach vs. modern approach, and so on)", - "bullet_points": [ - {{ - "heading": "Heading of the left column", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }}, - {{ - "heading": "Heading of the right column", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }} - ], - "key_message": "", - "img_keywords": "" - }} - ] -}} - - -### Output: -```json \ No newline at end of file diff --git a/langchain_templates/chat_prompts/refinement_template.txt b/langchain_templates/chat_prompts/refinement_template.txt deleted file mode 100644 index ec1569fe9f9e1016734691334a1470ad03cd7642..0000000000000000000000000000000000000000 --- a/langchain_templates/chat_prompts/refinement_template.txt +++ /dev/null @@ -1,49 +0,0 @@ -You are a helpful, intelligent chatbot. You follow instructions to refine an existing slide deck. -A list of user instructions is provided below in sequential order -- from the oldest to the latest. -The previously generated content of the slide deck in JSON format is also provided. -Follow the instructions to revise the content of the previously generated slides of the presentation on the given topic. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant content to each slide. -The content of the slides should be descriptive, verbose, and detailed. -If relevant, add one or two examples to illustrate the concept. -Unless explicitly specified with the topic, create about 10 slides. -You also fix any syntax error that may be present in the JSON-formatted content. - - -### List of instructions: -{instructions} - - -### Previously generated slide deck content as JSON: -{previous_content} - - -The output must be only a valid and syntactically correct JSON adhering to the following schema: -{{ - "title": "Presentation Title", - "slides": [ - {{ - "heading": "Heading for the First Slide", - "bullet_points": [ - "First bullet point", - [ - "Sub-bullet point 1", - "Sub-bullet point 2" - ], - "Second bullet point" - ] - }}, - {{ - "heading": "Heading for the Second Slide", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }} - ] -}} - - -### Output: -```json \ No newline at end of file diff --git a/langchain_templates/chat_prompts/refinement_template_v2_steps.txt b/langchain_templates/chat_prompts/refinement_template_v2_steps.txt deleted file mode 100644 index 95f1b0bb6288b384e71006daf3531eaa52b6509a..0000000000000000000000000000000000000000 --- a/langchain_templates/chat_prompts/refinement_template_v2_steps.txt +++ /dev/null @@ -1,70 +0,0 @@ -You are a helpful, intelligent chatbot. You follow instructions to refine an existing slide deck. -A list of user instructions is provided below in sequential order -- from the oldest to the latest. -The previously generated content of the slide deck in JSON format is also provided. -Follow the instructions to revise the content of the previously generated slides of the presentation on the given topic. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant content to each slide. -The content of the slides should be descriptive, verbose, and detailed. -If relevant, add one or two examples to illustrate the concept. -Unless explicitly specified with the topic, create about 10 slides. -You also fix any syntax error that may be present in the JSON-formatted content. - -A slide that describes a step-by-step/sequential process begins the bullet points -with a special marker >> - - -### List of instructions: -{instructions} - - -### Previously generated slide deck content as JSON: -{previous_content} - - -The output must be only a valid and syntactically correct JSON adhering to the following schema: -{{ - "title": "Presentation Title", - "slides": [ - {{ - "heading": "Heading for the First Slide", - "bullet_points": [ - "First bullet point", - [ - "Sub-bullet point 1", - "Sub-bullet point 2" - ], - "Second bullet point" - ], - "key_message": "" - }}, - {{ - "heading": "Heading for the Second Slide", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ], - "key_message": "The key message conveyed in this slide" - }}, - {{ - "heading": "A slide that describes a step-by-step/sequential process", - "bullet_points": [ - ">> The first step of the process (begins with special marker >>)", - ">> A second step (begins with >>)", - ">> Third step", - ], - "key_message": "" - }} - ] -}} - - -### Some more hints on the slide content and JSON output format: -- For two or three important slides, generate the key message that those slides convey and assign -them to the `key_message` elements of JSON output. -- Identify if a slide describes a step-by-step/sequential process, then begin the bullet points -with a special marker >>. Limit this to max two or three slides. - - -### Output: -```json \ No newline at end of file diff --git a/langchain_templates/chat_prompts/refinement_template_v3_two_cols.txt b/langchain_templates/chat_prompts/refinement_template_v3_two_cols.txt deleted file mode 100644 index b1d132a35e383379653d4b5ce53b906a74dec006..0000000000000000000000000000000000000000 --- a/langchain_templates/chat_prompts/refinement_template_v3_two_cols.txt +++ /dev/null @@ -1,85 +0,0 @@ -You are a helpful, intelligent chatbot. You follow instructions to refine an existing slide deck. -A list of user instructions is provided below in sequential order -- from the oldest to the latest. -The previously generated content of the slide deck in JSON format is also provided. -Follow the instructions to revise the content of the previously generated slides of the presentation on the given topic. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant content to each slide. -The content of each slide should be VERBOSE, DESCRIPTIVE, and very DETAILED. -If relevant, add one or two EXAMPLES to illustrate the concept. -For two or three important slides, generate the key message that those slides convey. -Identify if a slide describes a step-by-step/sequential process, then begin the bullet points with a special marker >>. Limit this to max two or three slides. -Also, add at least one slide with a double column layout by generating appropriate content based on the description in the JSON schema provided below. -ALWAYS add a concluding slide at the end, containing a list of the key takeways and an optional call-to-action if relevant to the context. -Unless explicitly instructed, create 10 TO 12 SLIDES in total. - - -### List of instructions: -{instructions} - - -### Previously generated slide deck content as JSON: -{previous_content} - - -The output must be only a valid and syntactically correct JSON adhering to the following schema: -{{ - "title": "Presentation Title", - "slides": [ - {{ - "heading": "Heading for the First Slide", - "bullet_points": [ - "First bullet point", - [ - "Sub-bullet point 1", - "Sub-bullet point 2" - ], - "Second bullet point" - ], - "key_message": "" - }}, - {{ - "heading": "Heading for the Second Slide", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ], - "key_message": "The key message conveyed in this slide" - }}, - {{ - "heading": "A slide that describes a step-by-step/sequential process", - "bullet_points": [ - ">> The first step of the process (begins with special marker >>)", - ">> A second step (begins with >>)", - ">> Third step", - ], - "key_message": "" - }}, - {{ - "heading": "A slide with a double column layout (useful for side-by-side comparison/contrasting of two related concepts, e.g., pros & cons, advantages & risks, old approach vs. modern approach, and so on)", - "bullet_points": [ - {{ - "heading": "Heading of the left column", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }}, - {{ - "heading": "Heading of the right column", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }} - ], - "key_message": "" - }} - ] -}} - - -### Output: -```json \ No newline at end of file diff --git a/langchain_templates/chat_prompts/refinement_template_v4_two_cols_img.txt b/langchain_templates/chat_prompts/refinement_template_v4_two_cols_img.txt deleted file mode 100644 index 73246c70441a326ded10d6dfb5c9019e126361b8..0000000000000000000000000000000000000000 --- a/langchain_templates/chat_prompts/refinement_template_v4_two_cols_img.txt +++ /dev/null @@ -1,114 +0,0 @@ -You are a helpful, intelligent assistant. You are experienced with PowerPoint. - -A list of user instructions is provided below in sequential order -- from the oldest to the latest. -The previously generated content of the slide deck in JSON format is also provided. -Follow the instructions to revise the content of the previously generated slides of the presentation on the given topic. -You will not repeat any slide. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant, detailed content to each slide. When relevant, add one or two EXAMPLES to illustrate the concept. -For two or three important slides, generate the key message that those slides convey. - -Identify if a slide describes a step-by-step/sequential process, then begin the bullet points with a special marker >>. Limit this to max two or three slides. -Also, add at least one slide with a double column layout by generating appropriate content based on the description in the JSON schema provided below. -In addition, for each slide, add image keywords based on the content of the respective slides. -These keywords will be later used to search for images from the Web relevant to the slide content. - -In addition, create one slide containing 4 TO 6 icons (pictograms) illustrating some key ideas/aspects/concepts relevant to the topic. -In this slide, each line of text will begin with the name of a relevant icon enclosed between [[ and ]]. -Select appropriate and exact icon names from the section provided below. - - -{icons_list} - - -The content of each slide should be VERBOSE, DESCRIPTIVE, and very DETAILED. Each bullet point should be detailed and explanatory, not just short phrases. - -ALWAYS add a concluding slide at the end, containing a list of the key takeaways and an optional call-to-action if relevant to the context. -Unless explicitly specified in the instructions below, create 10 TO 12 SLIDES in total. You must never create more tha 15 slides. - - -### List of instructions: -{instructions} - - -### Previously generated slide deck content as JSON: -{previous_content} - - -The output must be only a valid and syntactically correct JSON adhering to the following schema: -{{ - "title": "Presentation Title", - "slides": [ - {{ - "heading": "Heading for the First Slide", - "bullet_points": [ - "First bullet point", - [ - "Sub-bullet point 1", - "Sub-bullet point 2" - ], - "Second bullet point" - ], - "key_message": "", - "img_keywords": "a few keywords" - }}, - {{ - "heading": "Heading for the Second Slide", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ], - "key_message": "The key message conveyed in this slide", - "img_keywords": "some keywords for this slide" - }}, - {{ - "heading": "A slide illustrating key ideas/aspects/concepts (Hint: generate an appropriate heading)", - "bullet_points": [ - "[[icon name]] Some text", - "[[another icon name]] Some words describing this aspect", - "[[icon]] Another aspect highlighted here", - "[[an icon]] Another point here", - ], - "key_message": "", - "img_keywords": "" - }}, - {{ - "heading": "A slide that describes a step-by-step/sequential process", - "bullet_points": [ - ">> The first step of the process (begins with special marker >>)", - ">> A second step (begins with >>)", - ">> Third step", - ], - "key_message": "", - "img_keywords": "" - }}, - {{ - "heading": "A slide with a double column layout (useful for side-by-side comparison/contrasting of two related concepts, e.g., pros & cons, advantages & risks, old approach vs. modern approach, and so on)", - "bullet_points": [ - {{ - "heading": "Heading of the left column", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }}, - {{ - "heading": "Heading of the right column", - "bullet_points": [ - "First bullet point", - "Second bullet item", - "Third bullet point" - ] - }} - ], - "key_message": "", - "img_keywords": "" - }} - ] -}} - - -### Output: -```json \ No newline at end of file diff --git a/langchain_templates/template_combined.txt b/langchain_templates/template_combined.txt index 499cc85c360549e0e49ed524583aeddc459dc8e4..f12653f3aa483efa0838a1ad805fdd5347b6f10e 100644 --- a/langchain_templates/template_combined.txt +++ b/langchain_templates/template_combined.txt @@ -1,9 +1,5 @@ -You are a helpful, intelligent chatbot. Create the slides for a presentation on the given topic. -Include main headings for each slide, detailed bullet points for each slide. -Add relevant content to each slide. -The content should be descriptive, verbose, and detailed as much as possible. +You are a helpful, intelligent chatbot. Create the slides for a presentation on the given topic. Include main headings for each slide, detailed bullet points for each slide. Add relevant content to each slide. If relevant, add one or two examples to illustrate the concept. -Unless explicitly specified with the topic, create about 10 slides. Topic: diff --git a/legacy_app.py b/legacy_app.py deleted file mode 100644 index ef9b12aa8ea00957ae9f4fd03c19fa08c186996e..0000000000000000000000000000000000000000 --- a/legacy_app.py +++ /dev/null @@ -1,294 +0,0 @@ -import pathlib -import logging -import tempfile -from typing import List, Tuple - -import json5 -import metaphor_python as metaphor -import streamlit as st - -from helpers import llm_helper, pptx_helper -from global_config import GlobalConfig - - -APP_TEXT = json5.loads(open(GlobalConfig.APP_STRINGS_FILE, 'r', encoding='utf-8').read()) -GB_CONVERTER = 2 ** 30 - - -logger = logging.getLogger(__name__) - - -@st.cache_data -def get_contents_wrapper(text: str) -> str: - """ - Fetch and cache the slide deck contents on a topic by calling an external API. - - :param text: The presentation topic. - :return: The slide deck contents or outline in JSON format. - """ - - logger.info('LLM call because of cache miss...') - return llm_helper.generate_slides_content(text).strip() - - -@st.cache_resource -def get_metaphor_client_wrapper() -> metaphor.Metaphor: - """ - Create a Metaphor client for semantic Web search. - - :return: Metaphor instance. - """ - - return metaphor.Metaphor(api_key=GlobalConfig.METAPHOR_API_KEY) - - -@st.cache_data -def get_web_search_results_wrapper(text: str) -> List[Tuple[str, str]]: - """ - Fetch and cache the Web search results on a given topic. - - :param text: The topic. - :return: A list of (title, link) tuples. - """ - - results = [] - search_results = get_metaphor_client_wrapper().search( - text, - use_autoprompt=True, - num_results=5 - ) - - for a_result in search_results.results: - results.append((a_result.title, a_result.url)) - - return results - - -def build_ui(): - """ - Display the input elements for content generation. Only covers the first step. - """ - - # get_disk_used_percentage() - - st.title(APP_TEXT['app_name']) - st.subheader(APP_TEXT['caption']) - st.markdown( - 'Powered by' - ' [Mistral-7B-Instruct-v0.2](https://huggingface.co./mistralai/Mistral-7B-Instruct-v0.2).' - ) - st.markdown( - '*If the JSON is generated or parsed incorrectly, try again later by making minor changes' - ' to the input text.*' - ) - - with st.form('my_form'): - # Topic input - try: - with open(GlobalConfig.PRELOAD_DATA_FILE, 'r', encoding='utf-8') as in_file: - preload_data = json5.loads(in_file.read()) - except (FileExistsError, FileNotFoundError): - preload_data = {'topic': '', 'audience': ''} - - topic = st.text_area( - APP_TEXT['input_labels'][0], - value=preload_data['topic'] - ) - - texts = list(GlobalConfig.PPTX_TEMPLATE_FILES.keys()) - captions = [GlobalConfig.PPTX_TEMPLATE_FILES[x]['caption'] for x in texts] - - pptx_template = st.radio( - 'Select a presentation template:', - texts, - captions=captions, - horizontal=True - ) - - st.divider() - submit = st.form_submit_button('Generate slide deck') - - if submit: - # st.write(f'Clicked {time.time()}') - st.session_state.submitted = True - - # https://github.com/streamlit/streamlit/issues/3832#issuecomment-1138994421 - if 'submitted' in st.session_state: - progress_text = 'Generating the slides...give it a moment' - progress_bar = st.progress(0, text=progress_text) - - topic_txt = topic.strip() - generate_presentation(topic_txt, pptx_template, progress_bar) - - st.divider() - st.text(APP_TEXT['tos']) - st.text(APP_TEXT['tos2']) - - st.markdown( - '![Visitors]' - '(https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2Fbarunsaha%2Fslide-deck-ai&countColor=%23263759)' - ) - - -def generate_presentation(topic: str, pptx_template: str, progress_bar): - """ - Process the inputs to generate the slides. - - :param topic: The presentation topic based on which contents are to be generated. - :param pptx_template: The PowerPoint template name to be used. - :param progress_bar: Progress bar from the page. - """ - - topic_length = len(topic) - logger.debug('Input length:: topic: %s', topic_length) - - if topic_length >= 10: - logger.debug('Topic: %s', topic) - target_length = min(topic_length, GlobalConfig.LLM_MODEL_MAX_INPUT_LENGTH) - - try: - # Step 1: Generate the contents in JSON format using an LLM - json_str = process_slides_contents(topic[:target_length], progress_bar) - logger.debug('Truncated topic: %s', topic[:target_length]) - logger.debug('Length of JSON: %d', len(json_str)) - - # Step 2: Generate the slide deck based on the template specified - if len(json_str) > 0: - st.info( - 'Tip: The generated content doesn\'t look so great?' - ' Need alternatives? Just change your description text and try again.', - icon="💡️" - ) - else: - st.error( - 'Unfortunately, JSON generation failed, so the next steps would lead' - ' to nowhere. Try again or come back later.' - ) - return - - all_headers = generate_slide_deck(json_str, pptx_template, progress_bar) - - # Step 3: Bonus stuff: Web references and AI art - show_bonus_stuff(all_headers) - - except ValueError as ve: - st.error(f'Unfortunately, an error occurred: {ve}! ' - f'Please change the text, try again later, or report it, sharing your inputs.') - - else: - st.error('Not enough information provided! Please be little more descriptive :)') - - -def process_slides_contents(text: str, progress_bar: st.progress) -> str: - """ - Convert given text into structured data and display. Update the UI. - - :param text: The topic description for the presentation. - :param progress_bar: Progress bar for this step. - :return: The contents as a JSON-formatted string. - """ - - json_str = '' - - try: - logger.info('Calling LLM for content generation on the topic: %s', text) - json_str = get_contents_wrapper(text) - except Exception as ex: - st.error( - f'An exception occurred while trying to convert to JSON. It could be because of heavy' - f' traffic or something else. Try doing it again or try again later.' - f'\nError message: {ex}' - ) - - progress_bar.progress(50, text='Contents generated') - - with st.expander('The generated contents (in JSON format)'): - st.code(json_str, language='json') - - return json_str - - -def generate_slide_deck(json_str: str, pptx_template: str, progress_bar) -> List: - """ - Create a slide deck. - - :param json_str: The contents in JSON format. - :param pptx_template: The PPTX template name. - :param progress_bar: Progress bar. - :return: A list of all slide headers and the title. - """ - - progress_text = 'Creating the slide deck...give it a moment' - progress_bar.progress(75, text=progress_text) - - # # Get a unique name for the file to save -- use the session ID - # ctx = st_sr.get_script_run_ctx() - # session_id = ctx.session_id - # timestamp = time.time() - # output_file_name = f'{session_id}_{timestamp}.pptx' - - temp = tempfile.NamedTemporaryFile(delete=False, suffix='.pptx') - path = pathlib.Path(temp.name) - - logger.info('Creating PPTX file...') - all_headers = pptx_helper.generate_powerpoint_presentation( - json_str, - slides_template=pptx_template, - output_file_path=path - ) - progress_bar.progress(100, text='Done!') - - with open(path, 'rb') as f: - st.download_button('Download PPTX file', f, file_name='Presentation.pptx') - - if temp: - temp.close() - - return all_headers - - -def show_bonus_stuff(ppt_headers: List[str]): - """ - Show bonus stuff for the presentation. - - :param ppt_headers: A list of the slide headings. - """ - - # Use the presentation title and the slide headers to find relevant info online - logger.info('Calling Metaphor search...') - ppt_text = ' '.join(ppt_headers) - search_results = get_web_search_results_wrapper(ppt_text) - md_text_items = [] - - for (title, link) in search_results: - md_text_items.append(f'[{title}]({link})') - - with st.expander('Related Web references'): - st.markdown('\n\n'.join(md_text_items)) - - logger.info('Done!') - - # # Avoid image generation. It costs time and an API call, so just limit to the text generation. - # with st.expander('AI-generated image on the presentation topic'): - # logger.info('Calling SDXL for image generation...') - # # img_empty.write('') - # # img_text.write(APP_TEXT['image_info']) - # image = get_ai_image_wrapper(ppt_text) - # - # if len(image) > 0: - # image = base64.b64decode(image) - # st.image(image, caption=ppt_text) - # st.info('Tip: Right-click on the image to save it.', icon="💡️") - # logger.info('Image added') - - -def main(): - """ - Trigger application run. - """ - - build_ui() - - -if __name__ == '__main__': - main() diff --git a/helpers/llm_helper.py b/llm_helper.py similarity index 51% rename from helpers/llm_helper.py rename to llm_helper.py index c9ec2455acd706a629b4c60ca743b896039b5ff0..1c609d8f77c8da428df6da9d9e0772bd0de1e087 100644 --- a/helpers/llm_helper.py +++ b/llm_helper.py @@ -1,75 +1,34 @@ import logging import requests -from requests.adapters import HTTPAdapter -from urllib3.util import Retry - -from langchain_community.llms.huggingface_endpoint import HuggingFaceEndpoint -from langchain_core.language_models import LLM from global_config import GlobalConfig HF_API_URL = f"https://api-inference.huggingface.co/models/{GlobalConfig.HF_LLM_MODEL_NAME}" HF_API_HEADERS = {"Authorization": f"Bearer {GlobalConfig.HUGGINGFACEHUB_API_TOKEN}"} -REQUEST_TIMEOUT = 35 - -logger = logging.getLogger(__name__) -retries = Retry( - total=5, - backoff_factor=0.25, - backoff_jitter=0.3, - status_forcelist=[502, 503, 504], - allowed_methods={'POST'}, +logging.basicConfig( + level=GlobalConfig.LOG_LEVEL, + format='%(asctime)s - %(message)s', ) -adapter = HTTPAdapter(max_retries=retries) -http_session = requests.Session() -http_session.mount('https://', adapter) -http_session.mount('http://', adapter) - - -def get_hf_endpoint() -> LLM: - """ - Get an LLM via the HuggingFaceEndpoint of LangChain. - - :return: The LLM. - """ - - logger.debug('Getting LLM via HF endpoint') - return HuggingFaceEndpoint( - repo_id=GlobalConfig.HF_LLM_MODEL_NAME, - max_new_tokens=GlobalConfig.LLM_MODEL_MAX_OUTPUT_LENGTH, - top_k=40, - top_p=0.95, - temperature=GlobalConfig.LLM_MODEL_TEMPERATURE, - repetition_penalty=1.03, - streaming=True, - huggingfacehub_api_token=GlobalConfig.HUGGINGFACEHUB_API_TOKEN, - return_full_text=False, - stop_sequences=[''], - ) +# llm = None -def hf_api_query(payload: dict) -> dict: +def hf_api_query(payload: dict): """ Invoke HF inference end-point API. - :param payload: The prompt for the LLM and related parameters. - :return: The output from the LLM. + :param payload: The prompt for the LLM and related parameters + :return: The output from the LLM """ try: - response = http_session.post( - HF_API_URL, - headers=HF_API_HEADERS, - json=payload, - timeout=REQUEST_TIMEOUT - ) + response = requests.post(HF_API_URL, headers=HF_API_HEADERS, json=payload, timeout=15) result = response.json() except requests.exceptions.Timeout as te: - logger.error('*** Error: hf_api_query timeout! %s', str(te)) - result = [] + logging.error('*** Error: hf_api_query timeout! %s', str(te)) + result = {} return result @@ -78,8 +37,8 @@ def generate_slides_content(topic: str) -> str: """ Generate the outline/contents of slides for a presentation on a given topic. - :param topic: Topic on which slides are to be generated. - :return: The content in JSON format. + :param topic: Topic on which slides are to be generated + :return: The content in JSON format """ with open(GlobalConfig.SLIDES_TEMPLATE_FILE, 'r', encoding='utf-8') as in_file: @@ -87,8 +46,8 @@ def generate_slides_content(topic: str) -> str: template_txt = template_txt.replace('', topic) output = hf_api_query({ - 'inputs': template_txt, - 'parameters': { + "inputs": template_txt, + "parameters": { 'temperature': GlobalConfig.LLM_MODEL_TEMPERATURE, 'min_length': GlobalConfig.LLM_MODEL_MIN_OUTPUT_LENGTH, 'max_length': GlobalConfig.LLM_MODEL_MAX_OUTPUT_LENGTH, @@ -97,7 +56,7 @@ def generate_slides_content(topic: str) -> str: 'return_full_text': False, # "repetition_penalty": 0.0001 }, - 'options': { + "options": { 'wait_for_model': True, 'use_cache': True } @@ -111,7 +70,7 @@ def generate_slides_content(topic: str) -> str: # logging.debug(f'{json_end_idx=}') output = output[:json_end_idx] - logger.debug('generate_slides_content: output: %s', output) + logging.debug('generate_slides_content: output: %s', output) return output diff --git a/pptx_helper.py b/pptx_helper.py new file mode 100644 index 0000000000000000000000000000000000000000..6075932a74520aabf3e9bd9c201384de8341c987 --- /dev/null +++ b/pptx_helper.py @@ -0,0 +1,254 @@ +import logging +import pathlib +import re +import tempfile +from typing import List, Tuple + +import json5 +import pptx +import yaml + +from global_config import GlobalConfig + + +PATTERN = re.compile(r"^slide[ ]+\d+:", re.IGNORECASE) +SAMPLE_JSON_FOR_PPTX = ''' +{ + "title": "Understanding AI", + "slides": [ + { + "heading": "Introduction", + "bullet_points": [ + "Brief overview of AI", + [ + "Importance of understanding AI" + ] + ] + } + ] +} +''' + +logging.basicConfig( + level=GlobalConfig.LOG_LEVEL, + format='%(asctime)s - %(message)s', +) + + +def remove_slide_number_from_heading(header: str) -> str: + """ + Remove the slide number from a given slide header. + + :param header: The header of a slide + """ + + if PATTERN.match(header): + idx = header.find(':') + header = header[idx + 1:] + + return header + + +def generate_powerpoint_presentation( + structured_data: str, + as_yaml: bool, + slides_template: str, + output_file_path: pathlib.Path +) -> List: + """ + Create and save a PowerPoint presentation file containing the contents in JSON or YAML format. + + :param structured_data: The presentation contents as "JSON" (may contain trailing commas) or + YAML + :param as_yaml: True if the input data is in YAML format; False if it is in JSON format + :param slides_template: The PPTX template to use + :param output_file_path: The path of the PPTX file to save as + :return A list of presentation title and slides headers + """ + + if as_yaml: + # Avoid YAML mode: nested bullets can lead to incorrect YAML generation + try: + parsed_data = yaml.safe_load(structured_data) + except yaml.parser.ParserError as ype: + logging.error('*** YAML parse error: %s', str(ype)) + parsed_data = {'title': '', 'slides': []} + else: + # The structured "JSON" might contain trailing commas, so using json5 + parsed_data = json5.loads(structured_data) + + logging.debug( + "*** Using PPTX template: %s", + GlobalConfig.PPTX_TEMPLATE_FILES[slides_template]['file'] + ) + presentation = pptx.Presentation(GlobalConfig.PPTX_TEMPLATE_FILES[slides_template]['file']) + + # The title slide + title_slide_layout = presentation.slide_layouts[0] + slide = presentation.slides.add_slide(title_slide_layout) + title = slide.shapes.title + subtitle = slide.placeholders[1] + title.text = parsed_data['title'] + logging.debug('Presentation title is: %s', title.text) + subtitle.text = 'by Myself and SlideDeck AI :)' + all_headers = [title.text, ] + + # background = slide.background + # background.fill.solid() + # background.fill.fore_color.rgb = RGBColor.from_string('C0C0C0') # Silver + # title.text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 128) # Navy blue + + # Add contents in a loop + for a_slide in parsed_data['slides']: + bullet_slide_layout = presentation.slide_layouts[1] + slide = presentation.slides.add_slide(bullet_slide_layout) + shapes = slide.shapes + + title_shape = shapes.title + body_shape = shapes.placeholders[1] + title_shape.text = remove_slide_number_from_heading(a_slide['heading']) + all_headers.append(title_shape.text) + text_frame = body_shape.text_frame + + # The bullet_points may contain a nested hierarchy of JSON arrays + # In some scenarios, it may contain objects (dictionaries) because the LLM generated so + # ^ The second scenario is not covered + + flat_items_list = get_flat_list_of_contents(a_slide['bullet_points'], level=0) + + for an_item in flat_items_list: + paragraph = text_frame.add_paragraph() + paragraph.text = an_item[0] + paragraph.level = an_item[1] + + # The thank-you slide + last_slide_layout = presentation.slide_layouts[0] + slide = presentation.slides.add_slide(last_slide_layout) + title = slide.shapes.title + title.text = 'Thank you!' + + presentation.save(output_file_path) + + return all_headers + + +def get_flat_list_of_contents(items: list, level: int) -> List[Tuple]: + """ + Flatten a (hierarchical) list of bullet points to a single list containing each item and its level. + + :param items: A bullet point (string or list) + :param level: The current level of hierarchy + :return: A list of (bullet item text, hierarchical level) tuples + """ + + flat_list = [] + + for item in items: + if isinstance(item, str): + flat_list.append((item, level)) + elif isinstance(item, list): + flat_list = flat_list + get_flat_list_of_contents(item, level + 1) + + return flat_list + + +if __name__ == '__main__': + # bullets = [ + # 'Description', + # 'Types', + # [ + # 'Type A', + # 'Type B' + # ], + # 'Grand parent', + # [ + # 'Parent', + # [ + # 'Grand child' + # ] + # ] + # ] + + # output = get_flat_list_of_contents(bullets, level=0) + # for x in output: + # print(x) + + json_data = ''' + { + "title": "Understanding AI", + "slides": [ + { + "heading": "Introduction", + "bullet_points": [ + "Brief overview of AI", + [ + "Importance of understanding AI" + ] + ] + }, + { + "heading": "What is AI?", + "bullet_points": [ + "Definition of AI", + [ + "Types of AI", + [ + "Narrow or weak AI", + "General or strong AI" + ] + ], + "Differences between AI and machine learning" + ] + }, + { + "heading": "How AI Works", + "bullet_points": [ + "Overview of AI algorithms", + [ + "Types of AI algorithms", + [ + "Rule-based systems", + "Decision tree systems", + "Neural networks" + ] + ], + "How AI processes data" + ] + }, + { + "heading": "Pros of AI", + "bullet_points": [ + "Increased efficiency and productivity", + "Improved accuracy and precision", + "Enhanced decision-making capabilities", + "Personalized experiences" + ] + }, + { + "heading": "Cons of AI", + "bullet_points": [ + "Job displacement and loss of employment", + "Bias and discrimination", + "Privacy and security concerns", + "Dependence on technology" + ] + }, + { + "heading": "Future Prospects of AI", + "bullet_points": [ + "Advancements in fields such as healthcare and finance", + "Increased use" + ] + } + ] +}''' + + temp = tempfile.NamedTemporaryFile(delete=False, suffix='.pptx') + path = pathlib.Path(temp.name) + + generate_powerpoint_presentation( + json5.loads(json_data), + as_yaml=False, + output_file_path=path, + slides_template='Blank' + ) diff --git a/pptx_templates/Blank.pptx b/pptx_templates/Blank.pptx index 4703a8de72ede2078be75f597117b85b912627d4..89133e8abd0b6026d4679c6ed986fb11672fb03d 100644 Binary files a/pptx_templates/Blank.pptx and b/pptx_templates/Blank.pptx differ diff --git a/pptx_templates/Ion_Boardroom.pptx b/pptx_templates/Ion_Boardroom.pptx index dd2509b352aa6c09637d53926a20b858c46780b6..fd3e4577e7fe2c6aff9b65ef253728343cb0d3df 100644 Binary files a/pptx_templates/Ion_Boardroom.pptx and b/pptx_templates/Ion_Boardroom.pptx differ diff --git a/pptx_templates/Minimalist_sales_pitch.pptx b/pptx_templates/Minimalist_sales_pitch.pptx deleted file mode 100644 index 370c7ef58485dbbe4b8ed7c7177185a353815f08..0000000000000000000000000000000000000000 --- a/pptx_templates/Minimalist_sales_pitch.pptx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c78e378f5f5f2708034be3b2c8732da848e8e62378444e9e5a34497f3ea2e523 -size 935616 diff --git a/pptx_templates/Urban_monochrome.pptx b/pptx_templates/Urban_monochrome.pptx index dde4c687f4002eb85126c7ed5c9675bad132be1b..07384e652bce588b7474cb32c6174c34ac6ace6e 100644 Binary files a/pptx_templates/Urban_monochrome.pptx and b/pptx_templates/Urban_monochrome.pptx differ diff --git a/requirements.txt b/requirements.txt index 925c3ce8e5101de4b0f3ded1ef39767c99c3dd33..4575b23a97f1ce55274b82f09a3705f19df7444b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,33 +1,12 @@ -aiohttp==3.10.5 python-dotenv[cli]~=1.0.0 -gitpython==3.1.43 -json-repair==0.29.2 -idna==3.7 -jinja2==3.1.4 -Pillow==10.3.0 -pyarrow~=16.0.0 -pydantic==2.9.1 -langchain~=0.3.0 -langchain-core~=0.3.0 -langchain-community==0.3.0 -streamlit~=1.38.0 +langchain~=0.1.13 +# huggingface_hub +streamlit~=1.32.2 +clarifai==9.7.4 python-pptx -# metaphor-python +metaphor-python json5~=0.9.14 -requests~=2.32.3 - -transformers~=4.44.0 -torch==2.4.0 -langchain-community - -urllib3~=2.2.1 -lxml~=4.9.3 -tqdm~=4.66.5 -numpy~=1.25.2 -scikit-learn~=1.5.1 - -certifi==2024.8.30 -urllib3==2.2.3 - -anyio==4.4.0 +PyYAML~=6.0.1 +# curlify +requests~=2.31.0 \ No newline at end of file diff --git a/slides_for_this_project_by_this_project/515fc765-4aaf-4485-a421-551363710c03_1693157001.5142696.pptx b/slides_for_this_project_by_this_project/515fc765-4aaf-4485-a421-551363710c03_1693157001.5142696.pptx index 0b973369a203d7d04ffe2bc616d151fdb3b91497..15074b233ef1ef92f537539d5ce6d65ac56756a2 100644 Binary files a/slides_for_this_project_by_this_project/515fc765-4aaf-4485-a421-551363710c03_1693157001.5142696.pptx and b/slides_for_this_project_by_this_project/515fc765-4aaf-4485-a421-551363710c03_1693157001.5142696.pptx differ diff --git a/strings.json b/strings.json index 4f154e71cf625ea12998733ea79f9cda064e8bcf..861389fdee01c20271c7147d768a57543f5ca152 100644 --- a/strings.json +++ b/strings.json @@ -1,6 +1,6 @@ { - "app_name": ":green[SlideDeck AI $^{[Reloaded]}$]", - "caption": "*Converse, create, and improve your next PowerPoint slide deck*", + "app_name": "SlideDeck AI", + "caption": "*:green[Co-create your next PowerPoint slide deck with AI]*", "section_headers": [ "Step 1: Generate your content", "Step 2: Make it structured", @@ -23,15 +23,7 @@ ], "urls_info": "Here is a list of some online resources that you can consult for further information on this topic:", "image_info": "Got some more minutes? We are also trying to deliver an AI-generated art on the presentation topic, fresh off the studio, just for you!", - "content_generation_error": "Unfortunately, SlideDeck AI failed to generate any content for you! Please try again later.", - "json_parsing_error": "Unfortunately, SlideDeck AI failed to parse the response from LLM! Please try again by rephrasing the query or refreshing the page.", + "content_generation_failure_error": "Unfortunately, SlideDeck AI failed to generate any content for you! Please try again later.", "tos": "SlideDeck AI is an experimental prototype, and it has its limitations.\nPlease carefully review any and all AI-generated content.", - "tos2": "By using SlideDeck AI, you agree to fair and responsible usage.\nNo liability assumed by any party.", - "ai_greetings": [ - "How may I help you today?", - "Stuck with creating your presentation? Let me help you.", - "Looks like you have a looming deadline. Can I help you get started with your slide deck?", - "Hello! What topic do you have on your mind today?" - ], - "chat_placeholder": "Write the topic or instructions here" + "tos2": "By using SlideDeck AI, you agree to fair and responsible usage.\nNo liability assumed by any party." } \ No newline at end of file