diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 950b8aaab6ecda8be50365cc55a40387b61b4927..0000000000000000000000000000000000000000 --- a/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM python:3.10 - -WORKDIR /usr/src/app - -COPY requirements.txt ./ -RUN pip install --no-cache-dir -r requirements.txt - -COPY . . - -CMD [ "python", "app.py" ] \ No newline at end of file diff --git a/README.md b/README.md index 678b7f3b3a9229c37c06da2d402c2d87b3f464c9..a74c92a98e8efed548d8b3b42ec0a61edf34a75e 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ --- -title: Bot Recommendation -emoji: 🌖 +title: 🤖FPT.QAI AI Assistant +emoji: 🤖 colorFrom: red colorTo: gray sdk: gradio -sdk_version: 3.34.0 +sdk_version: 3.39.0 python_version: 3.9.13 app_file: app.py pinned: false +fullWidth: true + --- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference diff --git a/STANDARD_SOFTWARE LIFECYCLES.pdf b/STANDARD_SOFTWARE LIFECYCLES.pdf new file mode 100644 index 0000000000000000000000000000000000000000..26d40cca18fa63fbad5f02a85396576ad5e96dc1 Binary files /dev/null and b/STANDARD_SOFTWARE LIFECYCLES.pdf differ diff --git a/__pycache__/callback.cpython-39.pyc b/__pycache__/callback.cpython-39.pyc deleted file mode 100644 index 0a263d9cd0bf1a69db03ea8a5673be49edf41b71..0000000000000000000000000000000000000000 Binary files a/__pycache__/callback.cpython-39.pyc and /dev/null differ diff --git a/__pycache__/config.cpython-39.pyc b/__pycache__/config.cpython-39.pyc deleted file mode 100644 index cb51ade07ca6b229dafcdaf916159f6aac43856b..0000000000000000000000000000000000000000 Binary files a/__pycache__/config.cpython-39.pyc and /dev/null differ diff --git a/__pycache__/utils.cpython-39.pyc b/__pycache__/utils.cpython-39.pyc deleted file mode 100644 index 1330ed2afb56b402dff260aabf86a69bc330556e..0000000000000000000000000000000000000000 Binary files a/__pycache__/utils.cpython-39.pyc and /dev/null differ diff --git a/__pycache__/vector_db.cpython-39.pyc b/__pycache__/vector_db.cpython-39.pyc deleted file mode 100644 index 72fe757917d647c570441ec118a1cc6f9f1422fd..0000000000000000000000000000000000000000 Binary files a/__pycache__/vector_db.cpython-39.pyc and /dev/null differ diff --git a/app.py b/app.py index 61df7db69788c6347974d997e418e460652a4e56..ecd518206a73eceba2add6764719af5fa4f7e0c7 100644 --- a/app.py +++ b/app.py @@ -2,8 +2,10 @@ import gradio as gr from utils import * from chains.openai_model import OpenAIModel -from config import SEVER, PORT, DEBUG, DEPLOYMENT_ID, SAVE_DIR -from vector_db import delete_all, delete_file, handle_upload_file, update_file +from config import SEVER, PORT, DEBUG, DEPLOYMENT_ID +from vector_db import delete_all, delete_file, handle_upload_file, load_files_blob +from theme_dropdown import create_theme_dropdown + # Get and load new model def get_model(llm_model_name, temperature=0., top_p=1.0): @@ -15,126 +17,197 @@ def get_model(llm_model_name, temperature=0., top_p=1.0): def create_new_model(): return get_model(llm_model_name=DEPLOYMENT_ID) + def update_database(files_src): message = handle_upload_file(files_src) - saved_file = os.listdir(SAVE_DIR) - return gr.update(choices=saved_file), message + available_files = load_files_blob() + return gr.update(choices=available_files), message + + +def get_available_files(): + available_files = load_files_blob() + return gr.update(choices=available_files), gr.update(visible=True) + + +def update_example(chatbot, set_save_file_name): + from chains.related_question import RelatedQuestion + from chains.create_topic import CreateTopic + related_question = RelatedQuestion() + outputs = chatbot[-1][1].split("Docs FPT 🤖""" -with gr.Blocks() as demo: +with open("custom.css", "r", encoding="utf-8") as f: + customCSS = f.read() +dropdown, js = create_theme_dropdown() + +head = """ + + + + + FPT Bot + + + + + + +""" +checkbox_js = """ + async () => { + // Select all checkboxes with the class 'svelte-1ojmf70' + const checkboxes = document.querySelectorAll('.svelte-1ojmf70[type="checkbox"]'); + + // Add a click event listener to each checkbox + checkboxes.forEach(checkbox => { + checkbox.addEventListener('click', function() { + // If this checkbox was checked, uncheck all others + if (this.checked) { + checkboxes.forEach(otherCheckbox => { + if (otherCheckbox !== this) { + otherCheckbox.checked = false; + } + }); + } + }); + }); + } +""" + +title = """

AI Assistant 🤖

""" +logo = """ + +""" +user_input = gr.Textbox() + +with gr.Blocks(css=customCSS, theme='minatosnow/qaigpt') as demo: + samples = gr.State() user_name = gr.State("") history = gr.State([]) current_model = gr.State(create_new_model) + gr.HTML(head) - with gr.Row(): - with gr.Column(scale=1): - gr.HTML(title) + with gr.Row(elem_classes="status-div"): + with gr.Column(): + gr.HTML(logo) + user_info = gr.Markdown(value="getting user info...", elem_id="user_info") + with gr.Column(): status_text = "" status_display = gr.Markdown(status_text, elem_id="status_display") with gr.Row().style(equal_height=True): - with gr.Column(scale=5): - with gr.Row(): - chatbot = gr.Chatbot([], elem_id="chatbot").style(height="100%") - with gr.Row(): - with gr.Column(min_width=225, scale=12): - user_input = gr.Textbox( - show_label=False, placeholder="Enter here" - ).style(container=False) - # ask_examples_hidden = gr.Textbox(elem_id="hidden-message") - examples_questions = gr.Examples( - [ - "Bagaimana cara saya memohon sewa gerai?", - "Bagaimana cara saya pergi dari Komtar ke Pengkalan Weld?", - "Bagaimana cara saya boleh kemaskini Alamat Surat Menyurat Cukai Taksiran", - "What is event's permit at Penang?", - "How to apply car parking at Penang?", - "Where can I request for my event’s permit in Penang?" - ], - [user_input], - examples_per_page=6, + with gr.Column(scale=1): + with gr.Tab(label="Database"): + with gr.Accordion("Upload file", open=True, visible=False) as acc: + with gr.Row(): + index_files = gr.Files(label="Files", type="file") + + all_files = gr.Dropdown( + label=None, show_label=False, multiselect=True, choices=load_files_blob(), interactive=True ) - with gr.Column(min_width=42, scale=1): - submitBtn = gr.Button("Send", variant="primary") + with gr.Row(): + with gr.Column(min_width=42, scale=1): + delete_btn = gr.Button("", elem_classes="btn btn-del tooltip-btn tooltip-del") + with gr.Column(min_width=42, scale=1): + delete_all_btn = gr.Button("", elem_classes="btn btn-del-all tooltip-btn tooltip-del-all") + upload_files_btn = gr.Checkbox(label="Upload files", value=False, elem_classes="switch_checkbox") + local_db = gr.Checkbox(label="Local knowledge DB", value=False, elem_classes="switch_checkbox") + custom_websearch = gr.Checkbox(label="FPT web search", value=False, elem_classes="switch_checkbox") + local_db.change(None, _js=checkbox_js) + upload_files_btn.change(None, _js=checkbox_js) + custom_websearch.change(None, _js=checkbox_js) + + with gr.Tab(label="History"): + with gr.Accordion("Save/Load conversation history"): + with gr.Column(): + with gr.Row(): + with gr.Column(scale=6): + history_file_dropdown = gr.Dropdown( + label="Load conversation from list", + choices=get_history_names(plain=True), + multiselect=False, + container=False, + ) + with gr.Row(): + with gr.Column(min_width=42, scale=1): + historyRefreshBtn = gr.Button("🔄 Refresh") + with gr.Column(min_width=42, scale=1): + historyDeleteBtn = gr.Button("🗑️ Delete") + with gr.Row(): + with gr.Column(scale=6): + set_save_file_name = gr.Textbox( + show_label=True, + placeholder=None, + label="Topic (File name)", + ) + with gr.Column(scale=1): + saveHistoryBtn = gr.Button("💾 Save History") + + with gr.Tab(label="Theme"): + toggle_dark = gr.Button(value="Toggle Light/Dark") + toggle_dark.click( + None, + _js=""" + () => { + document.body.classList.toggle('dark'); + } + """, + ) + with gr.Column(scale=9): with gr.Row(): - emptyBtn = gr.Button( - "🧹 New conversation", elem_id="empty_btn") - retryBtn = gr.Button("🔄 Retry") - rec = gr.Button("⏺️Record") - record_audio = gr.inputs.Audio(source="microphone", type="filepath") + chatbot = gr.Chatbot(show_label=False, elem_classes="chatbot", show_share_button=False, height=650) with gr.Row(): - gr.Markdown( - """ - ## 💻 Key Feature - - Chat with an AI chatbot powered by OpenAI's chat API, using the **content of your research document**. - - Get **semantic search** answers from your document using **vector databases**. - - Perform a **Google search** within the app - - **Verify sources** for all generated results. - - Support converting **speech to text** for easy input. - ### Pine cone - Pinecone makes it easy to provide long-term memory for high-performance AI applications. - It's a managed, cloud-native vector database with a simple API and no infrastructure hassles. Pinecone serves fresh, filtered query results with low latency at the scale of billions of vectors. - https://www.pinecone.io/blog/azure/ - ### Azure OpenAI Service - https://learn.microsoft.com/en-us/legal/cognitive-services/openai/data-privacy - ## 📧 Contact - This tool has been developed by the R&D lab at **QAI** (FPT Software, Ha Noi, Viet Nam) - If you have any questions or feature requests, please feel free to reach us out at khangnvt1@fpt.com. - """ - ) + examples_questions = gr.Dataset(samples=[], components=[user_input], type="index") + with gr.Row(elem_classes="chatrow"): + with gr.Column(min_width=225, scale=10): + user_input = gr.Textbox(show_label=False, placeholder="Ask me anything...", container=False) - with gr.Column(min_width=50, scale=1.5): - with gr.Tab(label="ChatGPT"): - # gr.Markdown(f'

Azure OpenAI Service:here

') - index_files = gr.Files(label="Files", type="file", multiple=True) - use_websearch = gr.Checkbox(label="Google search", value=False, elem_classes="switch_checkbox") - custom_websearch = gr.Checkbox(label="Custom web search", value=False, elem_classes="switch_checkbox") - - with gr.Tab(label="Configuration"): - gr.Markdown( - "⚠️Be careful to change ⚠️\n\nIf you can't use it, please restore the default settings") - with gr.Accordion("Parameter", open=False): - temperature_slider = gr.Slider( - minimum=-0, - maximum=1.0, - value=0.0, - step=0.1, - interactive=True, - label="Temperature", - ) - top_p_slider = gr.Slider( - minimum=-0, - maximum=1.0, - value=1.0, - step=0.1, - interactive=True, - label="Top_p", - ) - user_identifier = gr.Textbox( - show_label=True, - placeholder="Enter here", - label="User name", - value=user_name.value, - lines=1, - ) - loadHistoryBtn = gr.Button("💾 Load History") - with gr.Tab(label="Knowledge DB"): - all_files = gr.Dropdown( - label="All available files:", multiselect=True, choices=os.listdir(SAVE_DIR), interactive=True - ) - with gr.Column(): - delete_btn = gr.Button("🗑️ Delete") - with gr.Column(): - delete_all_btn = gr.Button("🗑️ Delete all") - update_btn = gr.Button("🗑️ Update DB") + with gr.Column(min_width=42, scale=1): + submitBtn = gr.Button("", elem_classes="btn btn-send tooltip-btn tooltip-content-send") + with gr.Column(min_width=42, scale=1): + record_audio = gr.Audio(source="microphone", + show_label=False, + elem_classes="audio-btn btn", + type="filepath") + with gr.Column(min_width=42, scale=1): + emptyBtn = gr.Button( + "", elem_classes="btn btn-clear tooltip-btn tooltip-content-clear") + + with gr.Row(elem_classes="footer"): + gr.HTML("""""") + + def create_greeting(request: gr.Request): + if hasattr(request, "username") and request.username: # is not None or is not "" + print(f"User Name: {request.username}") + user_info, user_name = gr.Markdown.update(value=f"Hi {request.username}!"), request.username + else: + user_info, user_name = gr.Markdown.update(value="", visible=False), "" + current_model = get_model(llm_model_name=DEPLOYMENT_ID) + current_model.set_user_identifier(user_name) + return user_info, user_name, current_model, get_history_names(False, user_name) + demo.load(create_greeting, inputs=None, outputs=[user_info, user_name, current_model, history_file_dropdown]) + + examples_questions.click(load_example, inputs=[examples_questions, samples], outputs=[user_input]) index_files.change(update_database, [index_files], [all_files, status_display]) + upload_files_btn.change(get_available_files, None, [all_files, acc]) delete_all_btn.click(delete_all, None, [all_files, status_display, index_files]) delete_btn.click(delete_file, [all_files], [all_files, status_display, index_files]) - update_btn.click(update_file, None, [status_display]) - + # update_btn.click(update_fb, None, [status_display]) + emptyBtn.click( reset, inputs=[current_model], @@ -142,18 +215,37 @@ with gr.Blocks() as demo: show_progress=True, ) - retryBtn.click(retry, [chatbot, current_model, use_websearch, custom_websearch], [chatbot]) + # retryBtn.click(retry, [chatbot, current_model, use_websearch, custom_websearch], [chatbot, status_display]) + saveHistoryBtn.click(save_chat_history, [current_model, chatbot, set_save_file_name], [status_display]) + historyRefreshBtn.click(get_history_names, [gr.State(False), user_name], [history_file_dropdown]) + historyDeleteBtn.click(delete_chat_history, [current_model, history_file_dropdown], [status_display, history_file_dropdown, chatbot]) + history_file_dropdown.change(load_chat_history, [current_model, history_file_dropdown], [set_save_file_name, chatbot]) - loadHistoryBtn.click(load_chat_history, [current_model], [chatbot]) + record_audio.start_recording(None, None, None, + _js=""" + async () => { + document.querySelectorAll('.sm.secondary').forEach(function(element) { + element.classList.remove('secondary'); + element.classList.add('tertiary'); + }); + } + """ + ) - rec.click(transcribe, [current_model, record_audio], [user_input]) + record_audio.stop_recording(transcribe, [current_model, record_audio], [user_input, record_audio]) - user_identifier.change(set_user_indentifier, [current_model, user_identifier], None) + # user_identifier.change(set_user_identifier, [current_model, user_identifier], None) - user_input.submit(predict, [chatbot, current_model, user_input, use_websearch, custom_websearch], [chatbot, status_display], show_progress=True) + user_input.submit(predict, [chatbot, current_model, user_input, upload_files_btn, custom_websearch, local_db], + [chatbot, status_display], show_progress=True).then(update_example, [chatbot, set_save_file_name], + [chatbot, examples_questions, samples, + set_save_file_name]) user_input.submit(lambda: "", None, user_input) - submitBtn.click(predict, [chatbot, current_model, user_input, use_websearch, custom_websearch], [chatbot, status_display], show_progress=True) + submitBtn.click(predict, [chatbot, current_model, user_input, upload_files_btn, custom_websearch, local_db], + [chatbot, status_display], show_progress=True).then(update_example, [chatbot, set_save_file_name], + [chatbot, examples_questions, samples, + set_save_file_name]) submitBtn.click(lambda: "", None, user_input) demo.queue(concurrency_count=10).launch( - server_name=SEVER, server_port=PORT, debug=DEBUG) + server_name=SEVER, server_port=PORT, auth=get_auth(), debug=DEBUG) diff --git a/auth.json b/auth.json new file mode 100644 index 0000000000000000000000000000000000000000..6a9def1d1546b40cd5c0fc47a398406b3b0fc587 --- /dev/null +++ b/auth.json @@ -0,0 +1,14 @@ +{ + "user1": { + "username": "binh", + "password": "123456" + }, + "user2": { + "username": "hung", + "password": "123456" + }, + "user3": { + "username": "khang", + "password": "123456" + } +} \ No newline at end of file diff --git a/chains/__pycache__/azure_openai.cpython-39.pyc b/chains/__pycache__/azure_openai.cpython-39.pyc index c3e8fb0d27fb7dd9633b4e98f724ea1ef890eb7f..5c2dd6a149619b225f9a7d38fbe13f9473f83c18 100644 Binary files a/chains/__pycache__/azure_openai.cpython-39.pyc and b/chains/__pycache__/azure_openai.cpython-39.pyc differ diff --git a/chains/__pycache__/create_topic.cpython-39.pyc b/chains/__pycache__/create_topic.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3a09af9b6be8d25fe8d0128d38d16ba86d4458d Binary files /dev/null and b/chains/__pycache__/create_topic.cpython-39.pyc differ diff --git a/chains/__pycache__/custom_chain.cpython-39.pyc b/chains/__pycache__/custom_chain.cpython-39.pyc index 84206d2635fc771f66a4517c2f60c70e90085cd7..fa7a1bee9a7aa2064b45aff14adfb40121bf38b0 100644 Binary files a/chains/__pycache__/custom_chain.cpython-39.pyc and b/chains/__pycache__/custom_chain.cpython-39.pyc differ diff --git a/chains/__pycache__/decision_maker.cpython-39.pyc b/chains/__pycache__/decision_maker.cpython-39.pyc index 1370d2b986666e2a4ff49b6c6f65ea54f0723780..d51335990f15da9a9764fc7bb583667dd2f272f7 100644 Binary files a/chains/__pycache__/decision_maker.cpython-39.pyc and b/chains/__pycache__/decision_maker.cpython-39.pyc differ diff --git a/chains/__pycache__/model.cpython-39.pyc b/chains/__pycache__/model.cpython-39.pyc deleted file mode 100644 index 80bba651122ddeb1bde48d69f5f49652dd7e2314..0000000000000000000000000000000000000000 Binary files a/chains/__pycache__/model.cpython-39.pyc and /dev/null differ diff --git a/chains/__pycache__/multi_queries.cpython-39.pyc b/chains/__pycache__/multi_queries.cpython-39.pyc deleted file mode 100644 index 405c2d73d4fc3cc5138a24a5f904484928ac64cc..0000000000000000000000000000000000000000 Binary files a/chains/__pycache__/multi_queries.cpython-39.pyc and /dev/null differ diff --git a/chains/__pycache__/openai_model.cpython-39.pyc b/chains/__pycache__/openai_model.cpython-39.pyc index b848ce74b85ce935ecd65e3b9b4848601a97e013..7c7b92432db00eeaacb90b95237f67f28424cbf1 100644 Binary files a/chains/__pycache__/openai_model.cpython-39.pyc and b/chains/__pycache__/openai_model.cpython-39.pyc differ diff --git a/chains/__pycache__/related_question.cpython-39.pyc b/chains/__pycache__/related_question.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..09928a73fe961d298721924d6d8b4325363a269f Binary files /dev/null and b/chains/__pycache__/related_question.cpython-39.pyc differ diff --git a/chains/__pycache__/simple_chain.cpython-39.pyc b/chains/__pycache__/simple_chain.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..700f00907522210c77cda4e5b78b8f0518d9508d Binary files /dev/null and b/chains/__pycache__/simple_chain.cpython-39.pyc differ diff --git a/chains/__pycache__/stage_analyzer.cpython-39.pyc b/chains/__pycache__/stage_analyzer.cpython-39.pyc deleted file mode 100644 index f6c1e7c78cb92211df51d0875f59ba126b0b7dde..0000000000000000000000000000000000000000 Binary files a/chains/__pycache__/stage_analyzer.cpython-39.pyc and /dev/null differ diff --git a/chains/__pycache__/summary.cpython-39.pyc b/chains/__pycache__/summary.cpython-39.pyc index 4b26b91cbe4569ac979ab89bd766906151627a58..4d9ee1d70150d4a22ac2e8afd794976ecebedb9a 100644 Binary files a/chains/__pycache__/summary.cpython-39.pyc and b/chains/__pycache__/summary.cpython-39.pyc differ diff --git a/chains/__pycache__/web_search.cpython-39.pyc b/chains/__pycache__/web_search.cpython-39.pyc index a6a3fb161598a71aabb214fd7089624add58b562..7b2433afeeb8c9203677e82a147dc0402920f802 100644 Binary files a/chains/__pycache__/web_search.cpython-39.pyc and b/chains/__pycache__/web_search.cpython-39.pyc differ diff --git a/chains/create_topic.py b/chains/create_topic.py new file mode 100644 index 0000000000000000000000000000000000000000..59c6c525223e0ad1460f9ef1fadaef4f807019a3 --- /dev/null +++ b/chains/create_topic.py @@ -0,0 +1,26 @@ +from langchain.chains.llm import LLMChain +from langchain.prompts.chat import ( + ChatPromptTemplate, + SystemMessagePromptTemplate, + HumanMessagePromptTemplate) +from prompts.create_topic import SYSTEM_PROMPT_TEMPLATE, HUMAN_PROMPT_TEMPLATE +from config import OPENAI_API_TYPE, OPENAI_API_VERSION, OPENAI_API_KEY, OPENAI_API_BASE, DEPLOYMENT_ID +from chains.azure_openai import CustomAzureOpenAI + + +class CreateTopic(LLMChain): + llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, + openai_api_type=OPENAI_API_TYPE, + openai_api_base=OPENAI_API_BASE, + openai_api_version=OPENAI_API_VERSION, + openai_api_key=OPENAI_API_KEY, + temperature=0.0) + prompt = ChatPromptTemplate.from_messages( + [ + SystemMessagePromptTemplate.from_template(SYSTEM_PROMPT_TEMPLATE), + HumanMessagePromptTemplate.from_template(HUMAN_PROMPT_TEMPLATE) + ]) +if __name__ == "__main__": + chain = CreateTopic() + out = chain.predict(inputs="Hello", outputs="Hello! how can I assis you today?") + print(out) \ No newline at end of file diff --git a/chains/custom_chain.py b/chains/custom_chain.py index 395678f282ceee190dca5c8b1150fbf1bcded103..2051d573eea922455c670721a2c2092a3635a030 100644 --- a/chains/custom_chain.py +++ b/chains/custom_chain.py @@ -11,7 +11,6 @@ from config import DEPLOYMENT_ID from prompts.custom_chain import SYSTEM_PROMPT_TEMPLATE, HUMAN_PROMPT_TEMPLATE from config import OPENAI_API_TYPE, OPENAI_API_VERSION, OPENAI_API_KEY, OPENAI_API_BASE from chains.azure_openai import CustomAzureOpenAI -import os class MultiQueriesChain(LLMChain): llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, @@ -41,12 +40,11 @@ class CustomConversationalRetrievalChain(ConversationalRetrievalChain): docs = self.retriever.get_relevant_documents( question ) + # Add attribute to docs call docs.citation for (idx, d) in enumerate(docs): - if "https:" in d.metadata["source"]: - item = [d.page_content.strip("�"), d.metadata["source"]] - else: - item = [d.page_content.strip("�"), os.path.basename(d.metadata["source"])] - d.page_content = f'[{idx+1}]\t "{item[0]}"\nSource: {item[1]}' + item = [d.page_content.strip("�"), d.metadata["source"]] + d.page_content = f'[{idx+1}] {item[0]}' + d.metadata["source"] = f'{item[1]}' return self._reduce_tokens_below_limit(docs) # def _get_docs(self, question: str, inputs: Dict[str, Any]) -> List[Document]: # results = llm_chain.predict(question=question) + "\n" diff --git a/chains/decision_maker.py b/chains/decision_maker.py new file mode 100644 index 0000000000000000000000000000000000000000..2b2d74c4bf7bd2242e18d7a7f48ddc2c3b348f5e --- /dev/null +++ b/chains/decision_maker.py @@ -0,0 +1,29 @@ +from langchain.chains.llm import LLMChain +from langchain.prompts.chat import ( + ChatPromptTemplate, + SystemMessagePromptTemplate, + HumanMessagePromptTemplate) +from prompts.decision_maker import SYSTEM_PROMPT_TEMPLATE, HUMAN_PROMPT_TEMPLATE +from config import OPENAI_API_TYPE, OPENAI_API_VERSION, OPENAI_API_KEY, OPENAI_API_BASE, DEPLOYMENT_ID +from chains.azure_openai import CustomAzureOpenAI + +class DecisionMaker(LLMChain): + llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, + openai_api_type=OPENAI_API_TYPE, + openai_api_base=OPENAI_API_BASE, + openai_api_version=OPENAI_API_VERSION, + openai_api_key=OPENAI_API_KEY, + temperature=0.0) + prompt = ChatPromptTemplate.from_messages( + [ + SystemMessagePromptTemplate.from_template(SYSTEM_PROMPT_TEMPLATE), + HumanMessagePromptTemplate.from_template(HUMAN_PROMPT_TEMPLATE) + ]) + + +if __name__ == "__main__": + rel = DecisionMaker() + query = "Ai là tổng thống Mỹ" + + res = rel.predict(query = query) + print(res) \ No newline at end of file diff --git a/chains/openai_model.py b/chains/openai_model.py index 089b53988e69a6c63dcd9786398e3d156b8f04b6..6bd402ec208a43a32eb4556a25a5e5b8d8fd7270 100644 --- a/chains/openai_model.py +++ b/chains/openai_model.py @@ -1,34 +1,36 @@ import json import os +import re + import openai from langchain.prompts import PromptTemplate -from config import TIMEOUT_STREAM +from config import TIMEOUT_STREAM, HISTORY_DIR from vector_db import upload_file from callback import StreamingGradioCallbackHandler from queue import SimpleQueue, Empty, Queue from threading import Thread -from utils import history_file_path, load_lasted_file_username, add_source_numbers, add_details +from utils import add_source_numbers, add_details, web_citation, get_history_names from chains.custom_chain import CustomConversationalRetrievalChain from langchain.chains import LLMChain from chains.azure_openai import CustomAzureOpenAI from config import OPENAI_API_TYPE, OPENAI_API_VERSION, OPENAI_API_KEY, OPENAI_API_BASE, API_KEY, \ - DEPLOYMENT_ID, MODEL_ID, EMBEDDING_API_KEY, EMBEDDING_API_BASE - + DEPLOYMENT_ID, MODEL_ID +from cosmos_db import upsert_item, read_item, delete_items, query_items class OpenAIModel: def __init__( - self, - llm_model_name, - condense_model_name, - prompt_template="", - temperature=0.0, - top_p=1.0, - n_choices=1, - stop = None, - presence_penalty=0, - frequency_penalty=0, - user = None + self, + llm_model_name, + condense_model_name, + prompt_template="", + temperature=0.0, + top_p=1.0, + n_choices=1, + stop=None, + presence_penalty=0, + frequency_penalty=0, + user=None ): self.llm_model_name = llm_model_name self.condense_model_name = condense_model_name @@ -43,13 +45,14 @@ class OpenAIModel: self.history = [] self.user_identifier = user - def set_user_indentifier(self, new_user_indentifier): - self.user_identifier = new_user_indentifier + def set_user_identifier(self, new_user_identifier): + self.user_identifier = new_user_identifier def format_prompt(self, qa_prompt_template, condense_prompt_template): # Prompt template langchain qa_prompt = PromptTemplate(template=qa_prompt_template, input_variables=["question", "chat_history", "context"]) - condense_prompt = PromptTemplate(template=condense_prompt_template, input_variables=["question", "chat_history"]) + condense_prompt = PromptTemplate(template=condense_prompt_template, + input_variables=["question", "chat_history"]) return qa_prompt, condense_prompt def memory(self, inputs, outputs, last_k=3): @@ -65,166 +68,85 @@ class OpenAIModel: def delete_first_conversation(self): if self.history: self.history.pop(0) - + def delete_last_conversation(self): if len(self.history) > 0: self.history.pop() - - def auto_save_history(self, chatbot): - if self.user_identifier is not None: - file_path = history_file_path(self.user_identifier) - json_s = {"history": self.history, "chatbot": chatbot} - with open(file_path, "w", encoding='utf-8') as f: - json.dump(json_s, f, ensure_ascii=False) - - def load_history(self): - lasted_file = load_lasted_file_username(self.user_identifier) - if lasted_file is not None: - with open(f"{lasted_file}.json", "r", encoding="utf-8") as f: - json_s = json.load(f) - self.history = json_s["history"] - chatbot = json_s["chatbot"] - return chatbot - def audio_response(self, audio): - media_file = open(audio, 'rb') - response = openai.Audio.transcribe( - api_key=API_KEY, - model=MODEL_ID, - file=media_file - ) - return response["text"] + def save_history(self, chatbot, file_name): + message = upsert_item(self.user_identifier, file_name, self.history, chatbot) + return message - def inference(self, inputs, chatbot, streaming=False, use_websearch=False, custom_websearch=False, **kwargs): - if use_websearch or custom_websearch: - import requests + def load_history(self, file_name): + items = read_item(self.user_identifier, file_name) + return items['id'], items['chatbot'] - from bs4 import BeautifulSoup - from langchain.utilities.google_search import GoogleSearchAPIWrapper - from chains.web_search import GoogleWebSearch - from config import GOOGLE_API_KEY, GOOGLE_CSE_ID, CUSTOM_API_KEY, CUSTOM_CSE_ID - from chains.summary import WebSummary - from chains.multi_queries import MultiQueries - - status_text = "Retrieving information from the web" - yield chatbot, status_text - if use_websearch: - google_api_key = GOOGLE_API_KEY - google_cse_id = GOOGLE_CSE_ID - else: - google_api_key = CUSTOM_API_KEY - google_cse_id = CUSTOM_CSE_ID - search = GoogleSearchAPIWrapper(google_api_key=google_api_key, google_cse_id=google_cse_id) - - queries_chain = MultiQueries() - out = queries_chain.predict(question=inputs) - queries = list(map(lambda x: x.split(': ')[-1], out.split('\n\n'))) - print(queries) - results = [] - for query in queries: - search_rs = search.results(query, 2) - results.extend(search_rs) - reference_results = [] - display_append = [] - for idx, result in enumerate(results[:3]): - try: - head = requests.head(result['link']) - print(result["link"]) - status_text = "Access " + result['link'] - yield chatbot, status_text - if "text/html" in head.headers['Content-Type']: - html_response = requests.get(result['link']) - soup = BeautifulSoup(html_response.content, "html.parser") - try: - web_summary = WebSummary() - text = soup.get_text() - lines = (line.strip() for line in text.splitlines()) - # break multi-headlines into a line each - chunks = (phrase.strip() for line in lines for phrase in line.split(" ")) - # drop blank lines - text = '\n'.join(chunk for chunk in chunks if chunk) - - summary = web_summary.predict(question=inputs, doc=text) - print("Can access", result['link']) - # break into lines and remove leading and trailing space on each - - except: - print("Cannot access ", result['link']) - yield chatbot, status_text - reference_results.append([summary, result['link']]) - display_append.append( - f"{idx+1}. {result['title']}" - ) - except: - continue + def delete_history(self, file_name): + message = delete_items(self.user_identifier, file_name) + return message, get_history_names(False, self.user_identifier), [] - reference_results = add_source_numbers(reference_results) - display_append = '
' + "\n".join(display_append) + '
' + def audio_response(self, audio): + media_file = open(audio, 'rb') + response = openai.Audio.transcribe( + api_key=API_KEY, + model=MODEL_ID, + file=media_file + ) + return response["text"], None - status_text = "Request URL: " + OPENAI_API_BASE - yield chatbot, status_text - chatbot.append((inputs, "")) - web_search = GoogleWebSearch() - ai_response = web_search.predict(context="\n\n".join(reference_results), question=inputs, chat_history=self.history) - - chatbot[-1] = (chatbot[-1][0], ai_response+display_append) - self.memory(inputs, ai_response) - self.auto_save_history(chatbot) - yield chatbot, status_text - - else: + def inference(self, inputs, chatbot, streaming=False, upload_files_btn=False, custom_websearch=False, + local_db=False, + **kwargs): + if upload_files_btn or local_db: status_text = "Indexing files to vector database" yield chatbot, status_text + vectorstore = upload_file(upload_files_btn) - vectorstore = upload_file() - - status_text = "OpenAI version: " + OPENAI_API_VERSION - yield chatbot, status_text qa_prompt, condense_prompt = self.format_prompt(**kwargs) job_done = object() # signals the processing is done q = SimpleQueue() if streaming: timeout = TIMEOUT_STREAM - streaming_callback =[StreamingGradioCallbackHandler(q)] + streaming_callback = [StreamingGradioCallbackHandler(q)] # Define llm model - llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, + llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, openai_api_type=OPENAI_API_TYPE, openai_api_base=OPENAI_API_BASE, openai_api_version=OPENAI_API_VERSION, openai_api_key=OPENAI_API_KEY, temperature=self.temperature, - model_kwargs={"top_p": self.top_p}, - streaming=streaming,\ - callbacks=streaming_callback, + model_kwargs={"top_p": self.top_p}, + streaming=streaming, \ + callbacks=streaming_callback, request_timeout=timeout) - - condense_llm = CustomAzureOpenAI(deployment_name=self.condense_model_name, - openai_api_type=OPENAI_API_TYPE, - openai_api_base=OPENAI_API_BASE, - openai_api_version=OPENAI_API_VERSION, - openai_api_key=OPENAI_API_KEY, - temperature=self.temperature) + + condense_llm = CustomAzureOpenAI(deployment_name=self.condense_model_name, + openai_api_type=OPENAI_API_TYPE, + openai_api_base=OPENAI_API_BASE, + openai_api_version=OPENAI_API_VERSION, + openai_api_key=OPENAI_API_KEY, + temperature=self.temperature) status_text = "Request URL: " + OPENAI_API_BASE yield chatbot, status_text - # Create a funciton to call - this will run in a thread + # Create a function to call - this will run in a thread # Create a Queue object response_queue = SimpleQueue() def task(): - # Converation + RetrivalChain - qa = CustomConversationalRetrievalChain.from_llm(llm, vectorstore.as_retriever(k=5), - condense_question_llm = condense_llm, verbose=True, - condense_question_prompt=condense_prompt, - combine_docs_chain_kwargs={"prompt": qa_prompt}, - return_source_documents=True) + # Conversation + RetrivalChain + qa = CustomConversationalRetrievalChain.from_llm(llm, vectorstore.as_retriever( + search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.75}), + condense_question_llm=condense_llm, verbose=True, + condense_question_prompt=condense_prompt, + combine_docs_chain_kwargs={"prompt": qa_prompt}, + return_source_documents=True) # query with input and chat history response = qa({"question": inputs, "chat_history": self.history}) response_queue.put(response) q.put(job_done) - - + thread = Thread(target=task) thread.start() chatbot.append((inputs, "")) @@ -243,16 +165,114 @@ class OpenAIModel: # add citation info to response response = response_queue.get() relevant_docs = response["source_documents"] - reference_results = [d.page_content for d in relevant_docs] - display_append = add_details(reference_results) - display_append = "\n\n" + "
Citation"+ "".join(display_append) + "
" - chatbot[-1] = (chatbot[-1][0], content+display_append) + if len(relevant_docs) == 0: + display_append = "" + else: + if upload_files_btn: + reference_results = [d.page_content for d in relevant_docs] + reference_sources = [d.metadata["source"] for d in relevant_docs] + display_append = add_details(reference_results, reference_sources) + display_append = '
' + "\n".join(display_append) + '
' + else: + display_append = [] + for idx, d in enumerate(relevant_docs): + link = d.metadata["source"] + title = d.page_content.split("\n")[0] + # Remove non word characters and blank space before title + title = re.sub(r"[^\w\s]", "", title[:4]).strip() + display_append.append( + f'[{idx + 1}] {title}' + ) + display_append = '
' + "\n".join(display_append) + '
' + chatbot[-1] = (chatbot[-1][0], content + display_append) yield chatbot, status_text self.memory(inputs, content) - self.auto_save_history(chatbot) + # self.auto_save_history(chatbot) thread.join() + else: + import requests + + from langchain.utilities.google_search import GoogleSearchAPIWrapper + from chains.web_search import GoogleWebSearch + from config import GOOGLE_API_KEY, GOOGLE_CSE_ID + top_k = 4 + + if custom_websearch: + status_text = "Retrieving information from website FPTSoftware.com" + yield chatbot, status_text + params = { + "q": inputs, + "v": "\{539C9DC1-663A-418D-82A4-662D34EE34BC\}", + "p": 10, + "l": "en", + "s": "{EACE8DB5-668F-4357-9782-405070D28D11}", + "itemid": "\{91F4101E-B1F3-4905-A832-96F703D3FBB1\}", + } + req = requests.get( + "https://fptsoftware.com//sxa/search/results/?", + params=params + ) + res = json.loads(req.text) + results = [] + for r in res["Results"][:top_k]: + link = "https://fptsoftware.com" + r["Url"] + results.append({"link": link}) + reference_results, display_append = web_citation(inputs, results, True) + + reference_results = add_source_numbers(reference_results) + display_append = '
' + "\n".join(display_append) + '
' + status_text = "Request URL: " + OPENAI_API_BASE + yield chatbot, status_text + chatbot.append((inputs, "")) + web_search = GoogleWebSearch() + ai_response = web_search.predict(context="\n\n".join(reference_results), question=inputs, + chat_history=self.history) + + chatbot[-1] = (chatbot[-1][0], ai_response + display_append) + self.memory(inputs, ai_response) + # self.auto_save_history(chatbot) + yield chatbot, status_text + + + else: + from chains.decision_maker import DecisionMaker + from chains.simple_chain import SimpleChain + decision_maker = DecisionMaker() + simple_chain = SimpleChain() + decision = decision_maker.predict(question=inputs) + if "LLM Model" in decision: + status_text = "Request URL: " + OPENAI_API_BASE + yield chatbot, status_text + chatbot.append((inputs, "")) + ai_response = simple_chain.predict(question=inputs) + chatbot[-1] = (chatbot[-1][0], ai_response) + self.memory(inputs, ai_response) + # self.auto_save_history(chatbot) + yield chatbot, status_text + else: + status_text = "Retrieving information from Google" + yield chatbot, status_text + search = GoogleSearchAPIWrapper(google_api_key=GOOGLE_API_KEY, google_cse_id=GOOGLE_CSE_ID) + results = search.results(inputs, num_results=top_k) + reference_results, display_append = web_citation(inputs, results, False) + + reference_results = add_source_numbers(reference_results) + display_append = '
' + "\n".join(display_append) + '
' + status_text = "Request URL: " + OPENAI_API_BASE + yield chatbot, status_text + chatbot.append((inputs, "")) + web_search = GoogleWebSearch() + ai_response = web_search.predict(context="\n\n".join(reference_results), question=inputs, + chat_history=self.history) + + chatbot[-1] = (chatbot[-1][0], ai_response + display_append) + self.memory(inputs, ai_response) + # self.auto_save_history(chatbot) + yield chatbot, status_text + + if __name__ == '__main__': import os from config import OPENAI_API_KEY @@ -261,7 +281,8 @@ if __name__ == '__main__': ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate) - SYSTEM_PROMPT_TEMPLATE = "You're a helpfull assistant." + + SYSTEM_PROMPT_TEMPLATE = "You're a helpful assistant." HUMAN_PROMPT_TEMPLATE = "Human: {question}\n AI answer:" prompt = ChatPromptTemplate.from_messages( [ @@ -269,13 +290,12 @@ if __name__ == '__main__': HumanMessagePromptTemplate.from_template(HUMAN_PROMPT_TEMPLATE) ] ) - print("-===============") - llm = CustomAzureOpenAI(deployment_name="binh-gpt", + llm = CustomAzureOpenAI(deployment_name="binh-gpt", openai_api_key=OPENAI_API_KEY, openai_api_base=OPENAI_API_BASE, openai_api_version=OPENAI_API_VERSION, temperature=0, - model_kwargs={"top_p": 1.0},) + model_kwargs={"top_p": 1.0}, ) llm_chain = LLMChain( llm=llm, prompt=prompt diff --git a/chains/qaibot_chain.py b/chains/qaibot_chain.py new file mode 100644 index 0000000000000000000000000000000000000000..4da450f55b8b93aff9e5badd65e33a5ac69b8574 --- /dev/null +++ b/chains/qaibot_chain.py @@ -0,0 +1,81 @@ +import requests +import json + +from chains.azure_openai import CustomAzureOpenAI +from chains.decision_maker import DecisionMaker +from chains.simple_chain import SimpleChain +from bs4 import BeautifulSoup +from chains.summary import WebSummary +from langchain.utilities.google_search import GoogleSearchAPIWrapper +from config import OPENAI_API_TYPE, OPENAI_API_VERSION, OPENAI_API_KEY, OPENAI_API_BASE, DEPLOYMENT_ID, GOOGLE_API_KEY, GOOGLE_CSE_ID + +class QAIBotChain: + def __init__(self): + self.llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, + openai_api_type=OPENAI_API_TYPE, + openai_api_base=OPENAI_API_BASE, + openai_api_version=OPENAI_API_VERSION, + openai_api_key=OPENAI_API_KEY, + temperature=0.0) + self.decision = DecisionMaker() + self.simple_chain = SimpleChain() + self.summary = WebSummary() + + def run(self, question, custom_web_search=False, num_results=4): + if custom_web_search: + params = { + "q": question, + "v": "\{539C9DC1-663A-418D-82A4-662D34EE34BC\}", + "p": 10, + "l": "en", + "s": "{EACE8DB5-668F-4357-9782-405070D28D11}", + "itemid": "\{91F4101E-B1F3-4905-A832-96F703D3FBB1\}", + } + req = requests.get( + "https://fptsoftware.com//sxa/search/results/?", + params=params + ) + res = json.loads(req.text) + results = [] + for r in res["Results"][:num_results]: + link = "https://fptsoftware.com" + r["Url"] + results.append({"link": link}) + else: + decision = self.decision.predict(question=question) + if "LLM Model" in decision: + ai_response = self.simple_chain.predict(question=question) + return ai_response, False + else: + search = GoogleSearchAPIWrapper(google_api_key=GOOGLE_API_KEY, google_cse_id=GOOGLE_CSE_ID) + results = search.results(question, num_results=num_results) + reference_results = [] + display_append = [] + for idx, result in enumerate(results): + try: + head = requests.head(result['link']) + if "text/html" in head.headers['Content-Type']: + html_response = requests.get(result['link']) + soup = BeautifulSoup(html_response.content, "html.parser") + if custom_web_search: + title = result["title"] + else: + title = soup.find_all('title')[0].get_text() + try: + text = soup.get_text() + lines = (line.strip() for line in text.splitlines()) + # break multi-headlines into a line each + chunks = (phrase.strip() for line in lines for phrase in line.split(" ")) + # drop blank lines + text = '\n'.join(chunk for chunk in chunks if chunk) + + summary = self.web_summary.predict(question=question, doc=text) + print("Can access", result['link']) + except: + print("Cannot access ", result['link']) + reference_results.append([summary, result['link']]) + display_append.append( + f'{idx + 1}. {title}' + ) + except: + continue + return reference_results, display_append \ No newline at end of file diff --git a/chains/related_question.py b/chains/related_question.py new file mode 100644 index 0000000000000000000000000000000000000000..9e16e4d0bf8475129725afc2403a8eccdb9f4a45 --- /dev/null +++ b/chains/related_question.py @@ -0,0 +1,35 @@ +from langchain.chains import LLMChain +from langchain.prompts.chat import ( + ChatPromptTemplate, + SystemMessagePromptTemplate, + HumanMessagePromptTemplate) +from chains.azure_openai import CustomAzureOpenAI +from prompts.related_question import system_template, human_template +from config import OPENAI_API_TYPE, OPENAI_API_VERSION, OPENAI_API_KEY, OPENAI_API_BASE, DEPLOYMENT_ID, API_KEY +from langchain.chat_models import ChatOpenAI + +class RelatedQuestion(LLMChain): + prompt = ChatPromptTemplate.from_messages( + [SystemMessagePromptTemplate.from_template( + system_template), + HumanMessagePromptTemplate.from_template(human_template) + ]) + llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, + openai_api_type=OPENAI_API_TYPE, + openai_api_base=OPENAI_API_BASE, + openai_api_version=OPENAI_API_VERSION, + openai_api_key=OPENAI_API_KEY, + temperature=0.0) + +if __name__ == "__main__": + rel = RelatedQuestion() + inputs = "Hello bot" + outputs = "Hello! How can I assist you today?" + import re + pattern = "\d. {*.?}" + + res = rel.predict(inputs=inputs, outputs=outputs) + print(res) + out = list(map(lambda x: x.split('. ')[-1], res.split('\n'))) + results = [[a] for a in out] + print(results) diff --git a/chains/simple_chain.py b/chains/simple_chain.py new file mode 100644 index 0000000000000000000000000000000000000000..20e42343c27c2effcbe067606f3550a36cfa12d4 --- /dev/null +++ b/chains/simple_chain.py @@ -0,0 +1,22 @@ +from langchain.chains.llm import LLMChain +from langchain.prompts.chat import ( + ChatPromptTemplate, + SystemMessagePromptTemplate, + HumanMessagePromptTemplate) +from prompts.simple_chain import SYSTEM_PROMPT_TEMPLATE, HUMAN_PROMPT_TEMPLATE +from config import OPENAI_API_TYPE, OPENAI_API_VERSION, OPENAI_API_KEY, OPENAI_API_BASE, DEPLOYMENT_ID +from chains.azure_openai import CustomAzureOpenAI + + +class SimpleChain(LLMChain): + llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, + openai_api_type=OPENAI_API_TYPE, + openai_api_base=OPENAI_API_BASE, + openai_api_version=OPENAI_API_VERSION, + openai_api_key=OPENAI_API_KEY, + temperature=0.0) + prompt = ChatPromptTemplate.from_messages( + [ + SystemMessagePromptTemplate.from_template(SYSTEM_PROMPT_TEMPLATE), + HumanMessagePromptTemplate.from_template(HUMAN_PROMPT_TEMPLATE) + ]) diff --git a/chains/summary.py b/chains/summary.py index e1faacbf3f390377590e237ba300203514c63a74..cc60b172bd805a3812562dafeddba20b9668060b 100644 --- a/chains/summary.py +++ b/chains/summary.py @@ -7,6 +7,8 @@ from chains.azure_openai import CustomAzureOpenAI from prompts.summary import system_template, human_template from config import OPENAI_API_TYPE, OPENAI_API_VERSION, OPENAI_API_KEY, OPENAI_API_BASE, DEPLOYMENT_ID, API_KEY from langchain.chat_models import ChatOpenAI +import json +import requests class WebSummary(LLMChain): prompt = ChatPromptTemplate.from_messages( @@ -14,12 +16,28 @@ class WebSummary(LLMChain): system_template), HumanMessagePromptTemplate.from_template(human_template) ]) - # llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, - # openai_api_type=OPENAI_API_TYPE, - # openai_api_base=OPENAI_API_BASE, - # openai_api_version=OPENAI_API_VERSION, - # openai_api_key=OPENAI_API_KEY, - # temperature=0.0) - llm = ChatOpenAI(model_name="gpt-4", - openai_api_key=API_KEY, - temperature=0.0) \ No newline at end of file + llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, + openai_api_type=OPENAI_API_TYPE, + openai_api_base=OPENAI_API_BASE, + openai_api_version=OPENAI_API_VERSION, + openai_api_key=OPENAI_API_KEY, + temperature=0.0) + def run(self, question, num_result=4): + params = { + "q": question, + "v": "\{539C9DC1-663A-418D-82A4-662D34EE34BC\}", + "p": 10, + "l": "en", + "s": "{EACE8DB5-668F-4357-9782-405070D28D11}", + "itemid": "\{91F4101E-B1F3-4905-A832-96F703D3FBB1\}", + } + req = requests.get( + "https://fptsoftware.com//sxa/search/results/?", + params=params + ) + res = json.loads(req.text) + results = [] + for r in res["Results"][:num_result]: + link = "https://fptsoftware.com" + r["Url"] + results.append({"link": link}) + return results \ No newline at end of file diff --git a/chains/web_search.py b/chains/web_search.py index c389c79c452c88de02d1323dc22de2fa02749ecd..835d28e42f8d10c3214163717d07e22c15c3efc2 100644 --- a/chains/web_search.py +++ b/chains/web_search.py @@ -9,14 +9,11 @@ from chains.azure_openai import CustomAzureOpenAI from langchain.chat_models import ChatOpenAI class GoogleWebSearch(LLMChain): - # llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, - # openai_api_type=OPENAI_API_TYPE, - # openai_api_base=OPENAI_API_BASE, - # openai_api_version=OPENAI_API_VERSION, - # openai_api_key=OPENAI_API_KEY, - # temperature=0.0) - llm = ChatOpenAI(model_name="gpt-4", - openai_api_key=API_KEY, + llm = CustomAzureOpenAI(deployment_name=DEPLOYMENT_ID, + openai_api_type=OPENAI_API_TYPE, + openai_api_base=OPENAI_API_BASE, + openai_api_version=OPENAI_API_VERSION, + openai_api_key=OPENAI_API_KEY, temperature=0.0) prompt = ChatPromptTemplate.from_messages( [ diff --git a/config.py b/config.py index 306ccb8944e3a50f587831d0555d99d7beb3ff80..95ff95a1129ec8b51c46408479245d71a1c42b0b 100644 --- a/config.py +++ b/config.py @@ -2,45 +2,59 @@ import os # Folder HISTORY_DIR = "history" -SAVE_DIR = "documents" if not os.path.exists(HISTORY_DIR): os.makedirs(HISTORY_DIR) - -if not os.path.exists(SAVE_DIR): - os.makedirs(SAVE_DIR) - + # Whisper API -API_KEY = "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" +API_KEY = "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" MODEL_ID = "whisper-1" # Azure endpoint OPENAI_API_TYPE = "azure" OPENAI_API_VERSION = "2023-05-15" # Embedding openai -EMBEDDING_API_KEY = "e672d672cf2d4c778e352e2f88271ebc" +EMBEDDING_API_KEY = "776f46ee3ba445ebb2ecaeb988bfd04a" EMBEDDING_API_BASE = "https://qaigpt2.openai.azure.com/" EMBEDDING_DEPLOYMENT_ID = "embed" # ChatGPT -OPENAI_API_KEY = "1941ec6a33bd405bac7f2f800b10d171" -OPENAI_API_BASE = "https://qaigptjp.openai.azure.com/" +# EU Region +# OPENAI_API_KEY = "86f152e6a6ff46b1a71d5324a2823478" +# OPENAI_API_BASE ="https://qaigpteus2.openai.azure.com/" +# DEPLOYMENT_ID = "gpt" + +# France Region +OPENAI_API_KEY = "94e749c64288478d8861fcaf3c1b415f" +OPENAI_API_BASE ="https://qaigptfr.openai.azure.com/" DEPLOYMENT_ID = "gpt" # Pinecone vector DB PINECONE_API_KEY = "82b9902a-2908-4ece-88bf-483c413a91d7" PINECONE_ENVIRONMENT = "us-west1-gcp-free" INDEX_NAME = "text-indexing" +NAME_SPACE_1 = "documents" +NAME_SPACE_2 = "fanpage" # Google search API -GOOGLE_API_KEY = "AIzaSyBcwB4YIqjDcYr5XnPt5IrktqbH4Mb_1hE" -GOOGLE_CSE_ID = "e61c62a86e2b848fd" +GOOGLE_API_KEY="AIzaSyBcwB4YIqjDcYr5XnPt5IrktqbH4Mb_1hE" +GOOGLE_CSE_ID="e61c62a86e2b848fd" # Custom google search API CUSTOM_API_KEY = "AIzaSyDycFFOFtPg123bm9N3BRCy_q5gyEk7fzs" -CUSTOM_CSE_ID = "3364dacc2a4144b22" +CUSTOM_CSE_ID = "a1bdbedc30f2b4790" # Local host TIMEOUT_STREAM = 60 SEVER = "0.0.0.0" PORT = 7860 DEBUG = True + +# Azure blob storage +CONNECTION_STRING = "DefaultEndpointsProtocol=https;AccountName=qaigpt;AccountKey=osgfH8+I/azlhNNn5Ps3jpYLgCfnXKuOZPQ4fkpwVX/tNISdyf8jhfq37lKxJSDIORgDPA7wPg5v+AStb47TRg==;EndpointSuffix=core.windows.net" +CONTAINER_NAME = "fptdocuments" + +# Azure cosmos db +CREDENTIAL = "6t1RmAaF6onypDHHtAVrcnNOwPZpPusTiq9N5tHl8HpkDEPZn5y0TJbdCNBga1JuKBJaKlqnc09JACDblCPpbQ==" +ENDPOINT = 'https://qaigpt.documents.azure.com:443/' +DATABASE = "chat_gpt" +CONTAINER_COSMOS = "history" \ No newline at end of file diff --git a/cosmos_db.py b/cosmos_db.py new file mode 100644 index 0000000000000000000000000000000000000000..2eb89adff652b2fa8aeb9cab6355fd01264a21fc --- /dev/null +++ b/cosmos_db.py @@ -0,0 +1,73 @@ +from azure.cosmos import CosmosClient, PartitionKey +from config import ENDPOINT, CREDENTIAL, DATABASE, CONTAINER_COSMOS +from datetime import date, datetime +import json + +_client = CosmosClient( + url=ENDPOINT, + credential=CREDENTIAL, +) + +database = _client.create_database_if_not_exists(DATABASE) +_container = database.create_container_if_not_exists( + CONTAINER_COSMOS, + partition_key=PartitionKey("/user_id") +) + +def json_serial(obj): + """JSON serializer for objects not serializable by default json code""" + + if isinstance(obj, (datetime, date)): + return obj.isoformat() + raise TypeError ("Type %s not serializable" % type(obj)) + +def upsert_item(user_id, file_name, history, chatbot): + response = _container.upsert_item( + body={ + "id": file_name, + "user_id": user_id, + "date": json.dumps(datetime.utcnow(), default=json_serial), + "history": history, + "chatbot": chatbot + } + ) + + message = f'Upsert {file_name} succesfully' + return message + +def read_item(user_id, file_name): + response = _container.read_item(item=file_name, partition_key=user_id) + return response + + +def query_items(user_id, file_name): + response = list(_container.query_items( + query="SELECT * FROM r WHERE r.user_id=@user_id AND r.id=@id", + parameters=[ + {"name": "@user_id", "value": user_id}, {"name": "@id", "value": file_name} + ], + enable_cross_partition_query=True + )) + + return response + +def query_item(user_id): + response = list(_container.query_items( + query="SELECT * FROM r WHERE r.user_id=@user_id", + parameters=[ + {"name": "@user_id", "value": user_id} + ], + enable_cross_partition_query=True + )) + return response + +def delete_items(user_id, file_name): + response = _container.delete_item(item=file_name, partition_key=user_id) + message = f'Delete {file_name} succesfully' + return message + +if __name__ == '__main__': + mes = query_item("khanh") + docs = [m["id"] for m in mes] + print(docs) + \ No newline at end of file diff --git a/custom.css b/custom.css new file mode 100644 index 0000000000000000000000000000000000000000..1a4c74591d5f08a45ca45b86908bf755fed156ad --- /dev/null +++ b/custom.css @@ -0,0 +1,1026 @@ +:root { + --chatbot-color-light: #000000; + --chatbot-color-dark: #FFFFFF; + --chatbot-background-color-light: #F3F3F3; + --chatbot-background-color-dark: #121111; + --message-user-background-color-light: #2685b5; + --message-user-background-color-dark: #2685b5; + --message-bot-background-color-light: #F3F3F3; + --message-bot-background-color-dark: #2C2C2C; + --switch-checkbox-color-light: #e9e9ec; + --switch-checkbox-color-dark: #515151; + --switch-checkbox-marked-color: #2685b5; + --cib-shadow-card: 0px 0.3px 0.9px rgba(0, 0, 0, 0.12), 0px 1.6px 3.6px rgba(0, 0, 0, 0.16); + --message-font-size: 15px; + --background-gradient: linear-gradient(90deg, rgb(239, 242, 247) 0%, 7.60286%, rgb(237, 240, 249) 15.2057%, 20.7513%, rgb(235, 239, 248) 26.297%, 27.6386%, rgb(235, 239, 248) 28.9803%, 38.2826%, rgb(231, 237, 249) 47.585%, 48.1216%, rgb(230, 236, 250) 48.6583%, 53.1306%, rgb(228, 236, 249) 57.6029%, 61.5385%, rgb(227, 234, 250) 65.4741%, 68.7835%, rgb(222, 234, 250) 72.093%, 75.7603%, rgb(219, 230, 248) 79.4275%, 82.8265%, rgb(216, 229, 248) 86.2254%, 87.8354%, rgb(213, 228, 249) 89.4454%, 91.8605%, rgb(210, 226, 249) 94.2755%, 95.4383%, rgb(209, 225, 248) 96.6011%, 98.3005%, rgb(208, 224, 247) 100%); + --background-gradient-dark: #0b0f19; +} + +gradio-app { + background: var(--background-gradient) !important; +} + +.dark gradio-app { + background: var(--background-gradient-dark) !important; +} + +#app_title { + font-weight: var(--prose-header-text-weight); + font-size: var(--text-xxl); + line-height: 1.3; + text-align: left; + margin-top: 6px; + white-space: nowrap; +} + +#description { + text-align: center; + margin: 32px 0 4px 0; +} + + +div.form { + background: none !important; + border: none !important; +} + + +#advanced_warning { + display: flex; + flex-wrap: wrap; + flex-direction: column; + align-content: center; +} + +/* gradio的页脚信息 */ +footer { + margin-top: 15px !important; + font-size: 85%; + display: inline-block; + text-align: center; + opacity: 0.60; + position: absolute; + max-height: 30px; + width: 100% !important; +} + +footer[class^="svelte-"] { + display: none !important; +} + +#footer { + text-align: center; +} + +#footer div { + display: inline-block; +} + +#footer .versions { + font-size: 85%; + opacity: 0.60; +} + +#float_display { + position: absolute; + max-height: 30px; +} + +#toast-update { + position: absolute; + display: flex; + top: -500px; + width: 100%; + justify-content: center; + z-index: var(--layer-top); + transition: top 0.3s ease-out; +} + +#check-chuanhu-update { + position: absolute; + align-items: center; + display: flex; + flex-direction: column; + justify-content: center; + margin: var(--size-6) var(--size-4); + box-shadow: var(--shadow-drop-lg); + border: 1px solid var(--block-label-border-color); + border-radius: var(--container-radius); + background: var(--background-fill-primary); + padding: var(--size-4) var(--size-6); + min-width: 360px; + max-width: 480px; + overflow: hidden; + pointer-events: auto; +} + +#version-info-title { + font-size: 1.2em; + font-weight: bold; + text-align: start; + width: 100%; +} + +#release-note-wrap { + width: 100%; + max-width: 400px; + height: 120px; + border: solid 1px var(--border-color-primary); + overflow: auto; + padding: 0 8px; +} + +#release-note-wrap.hideK { + display: none; +} + +/*.chatrow {*/ +/* gap: 0 !important;*/ +/*}*/ + +.record-icon svelte-1thnwz { + display: none !important; +} + +.btn, .audio-btn .sm.secondary, .mic-wrap, .audio-btn .sm.tertiary { + height: 48px !important; + margin: 0 !important; + padding: 0 5px 0 !important; + display: inline-block; +} + +.audio-btn { + border: 0 !important; + position: relative; + background: none !important; +} + +.mic-wrap { + position: absolute; + padding: 0 !important; + top: 0; + left: 0; + z-index: 1; +} + +.audio-btn .sm.secondary, .audio-btn .sm.tertiary { + color: transparent; + border: none !important; +} + +.audio-btn .record-icon { + display: none !important; +} + +.dark .btn-send { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="20" height="20" viewBox="0 0 20 20"%3E%3Cpath fill="white" d="M2.724 2.053a.5.5 0 0 0-.707.576l1.498 5.618a.5.5 0 0 0 .4.364l6.855 1.142c.279.047.279.447 0 .494l-6.854 1.142a.5.5 0 0 0-.401.364l-1.498 5.618a.5.5 0 0 0 .707.576l15-7.5a.5.5 0 0 0 0-.894l-15-7.5Z"%2F%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.dark .btn-clear { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="20" height="20" viewBox="0 0 16 16"%3E%3Cpath fill="white" fill-rule="evenodd" d="M15.963 7.23A8 8 0 0 1 .044 8.841a.75.75 0 0 1 1.492-.158a6.5 6.5 0 1 0 9.964-6.16V4.25a.75.75 0 0 1-1.5 0V0h4.25a.75.75 0 0 1 0 1.5h-1.586a8.001 8.001 0 0 1 3.299 5.73ZM7 2a1 1 0 1 0 0-2a1 1 0 0 0 0 2Zm-2.25.25a1 1 0 1 1-2 0a1 1 0 0 1 2 0ZM1.5 6a1 1 0 1 0 0-2a1 1 0 0 0 0 2Z" clip-rule="evenodd"%2F%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.dark .btn-record, .dark .audio-btn .sm.secondary { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="20" height="20" viewBox="0 0 20 20"%3E%3Cpath fill="white" d="M4.5 10a.5.5 0 0 0-1 0a5.5 5.5 0 0 0 5 5.478V17.5a.5.5 0 0 0 1 0v-.706A5.48 5.48 0 0 1 9 14.5A4.5 4.5 0 0 1 4.5 10ZM12 5v4.6a5.514 5.514 0 0 0-2.79 3.393A3 3 0 0 1 6 10V5a3 3 0 0 1 6 0Zm5 9.5a2.5 2.5 0 1 1-5 0a2.5 2.5 0 0 1 5 0Zm2 0a4.5 4.5 0 1 1-9 0a4.5 4.5 0 0 1 9 0Zm-8 0a3.5 3.5 0 1 0 7 0a3.5 3.5 0 0 0-7 0Z"%2F%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.dark .audio-btn .sm.tertiary { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="20" height="20" viewBox="0 0 24 24"%3E%3Cdefs%3E%3Cfilter id="svgSpinnersGooeyBalls10"%3E%3CfeGaussianBlur in="SourceGraphic" result="y" stdDeviation="1.5"%2F%3E%3CfeColorMatrix in="y" result="z" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7"%2F%3E%3CfeBlend in="SourceGraphic" in2="z"%2F%3E%3C%2Ffilter%3E%3C%2Fdefs%3E%3Cg fill="white" filter="url(%23svgSpinnersGooeyBalls10)"%3E%3Ccircle cx="4" cy="12" r="3"%3E%3Canimate attributeName="cx" calcMode="spline" dur="0.75s" keySplines=".56%2C.52%2C.17%2C.98%3B.56%2C.52%2C.17%2C.98" repeatCount="indefinite" values="4%3B9%3B4"%2F%3E%3Canimate attributeName="r" calcMode="spline" dur="0.75s" keySplines=".56%2C.52%2C.17%2C.98%3B.56%2C.52%2C.17%2C.98" repeatCount="indefinite" values="3%3B8%3B3"%2F%3E%3C%2Fcircle%3E%3Ccircle cx="15" cy="12" r="8"%3E%3Canimate attributeName="cx" calcMode="spline" dur="0.75s" keySplines=".56%2C.52%2C.17%2C.98%3B.56%2C.52%2C.17%2C.98" repeatCount="indefinite" values="15%3B20%3B15"%2F%3E%3Canimate attributeName="r" calcMode="spline" dur="0.75s" keySplines=".56%2C.52%2C.17%2C.98%3B.56%2C.52%2C.17%2C.98" repeatCount="indefinite" values="8%3B3%3B8"%2F%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.dark .btn-del { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="24" height="24" viewBox="0 0 24 24"%3E%3Cpath fill="white" d="m18 9l-5-5v3q0 .825.588 1.413T15 9h3Zm0 10.425L16.6 20.8q-.275.275-.688.288T15.2 20.8q-.275-.275-.275-.7t.275-.7l1.4-1.4l-1.4-1.4q-.275-.275-.275-.7t.275-.7q.275-.275.7-.275t.7.275l1.4 1.4l1.4-1.4q.275-.275.688-.287t.712.287q.275.275.275.7t-.275.7L19.425 18l1.375 1.4q.275.275.288.688t-.288.712q-.275.275-.7.275t-.7-.275L18 19.425ZM6 22q-.825 0-1.413-.588T4 20V4q0-.825.588-1.413T6 2h7.175q.4 0 .763.15t.637.425l4.85 4.85q.275.275.425.638t.15.762v3.525q-.475-.175-.988-.263T17.976 12q-2.5 0-4.237 1.738T12 17.974q0 1.125.4 2.163T13.55 22H6Z"%2F%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.dark .btn-del-all { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="24" height="24" viewBox="0 0 24 24"%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cpath d="M24 0v24H0V0h24ZM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018Zm.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022Zm-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01l-.184-.092Z"%2F%3E%3Cpath fill="white" d="M4 3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V7.5a2 2 0 0 0-2-2h-7.52l-1.399-1.75A2 2 0 0 0 9.52 3H4Zm5.172 7.172a1 1 0 0 1 1.414 0L12 11.586l1.414-1.414a1 1 0 1 1 1.414 1.414L13.414 13l1.414 1.414a1 1 0 0 1-1.414 1.414L12 14.414l-1.414 1.414a1 1 0 1 1-1.414-1.414L10.586 13l-1.414-1.414a1 1 0 0 1 0-1.414Z"%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.btn-send { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="20" height="20" viewBox="0 0 20 20"%3E%3Cpath fill="%232685b5" d="M2.724 2.053a.5.5 0 0 0-.707.576l1.498 5.618a.5.5 0 0 0 .4.364l6.855 1.142c.279.047.279.447 0 .494l-6.854 1.142a.5.5 0 0 0-.401.364l-1.498 5.618a.5.5 0 0 0 .707.576l15-7.5a.5.5 0 0 0 0-.894l-15-7.5Z"%2F%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.btn-clear { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="20" height="20" viewBox="0 0 16 16"%3E%3Cpath fill="%232685b5" fill-rule="evenodd" d="M15.963 7.23A8 8 0 0 1 .044 8.841a.75.75 0 0 1 1.492-.158a6.5 6.5 0 1 0 9.964-6.16V4.25a.75.75 0 0 1-1.5 0V0h4.25a.75.75 0 0 1 0 1.5h-1.586a8.001 8.001 0 0 1 3.299 5.73ZM7 2a1 1 0 1 0 0-2a1 1 0 0 0 0 2Zm-2.25.25a1 1 0 1 1-2 0a1 1 0 0 1 2 0ZM1.5 6a1 1 0 1 0 0-2a1 1 0 0 0 0 2Z" clip-rule="evenodd"%2F%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.btn-record, .audio-btn .sm.secondary { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="20" height="20" viewBox="0 0 20 20"%3E%3Cpath fill="%232685b5" d="M4.5 10a.5.5 0 0 0-1 0a5.5 5.5 0 0 0 5 5.478V17.5a.5.5 0 0 0 1 0v-.706A5.48 5.48 0 0 1 9 14.5A4.5 4.5 0 0 1 4.5 10ZM12 5v4.6a5.514 5.514 0 0 0-2.79 3.393A3 3 0 0 1 6 10V5a3 3 0 0 1 6 0Zm5 9.5a2.5 2.5 0 1 1-5 0a2.5 2.5 0 0 1 5 0Zm2 0a4.5 4.5 0 1 1-9 0a4.5 4.5 0 0 1 9 0Zm-8 0a3.5 3.5 0 1 0 7 0a3.5 3.5 0 0 0-7 0Z"%2F%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.audio-btn .sm.tertiary { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="24" height="24" viewBox="0 0 24 24"%3E%3Cdefs%3E%3Cfilter id="svgSpinnersGooeyBalls10"%3E%3CfeGaussianBlur in="SourceGraphic" result="y" stdDeviation="1.5"%2F%3E%3CfeColorMatrix in="y" result="z" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7"%2F%3E%3CfeBlend in="SourceGraphic" in2="z"%2F%3E%3C%2Ffilter%3E%3C%2Fdefs%3E%3Cg fill="%232685b5" filter="url(%23svgSpinnersGooeyBalls10)"%3E%3Ccircle cx="4" cy="12" r="3"%3E%3Canimate attributeName="cx" calcMode="spline" dur="0.75s" keySplines=".56%2C.52%2C.17%2C.98%3B.56%2C.52%2C.17%2C.98" repeatCount="indefinite" values="4%3B9%3B4"%2F%3E%3Canimate attributeName="r" calcMode="spline" dur="0.75s" keySplines=".56%2C.52%2C.17%2C.98%3B.56%2C.52%2C.17%2C.98" repeatCount="indefinite" values="3%3B8%3B3"%2F%3E%3C%2Fcircle%3E%3Ccircle cx="15" cy="12" r="8"%3E%3Canimate attributeName="cx" calcMode="spline" dur="0.75s" keySplines=".56%2C.52%2C.17%2C.98%3B.56%2C.52%2C.17%2C.98" repeatCount="indefinite" values="15%3B20%3B15"%2F%3E%3Canimate attributeName="r" calcMode="spline" dur="0.75s" keySplines=".56%2C.52%2C.17%2C.98%3B.56%2C.52%2C.17%2C.98" repeatCount="indefinite" values="8%3B3%3B8"%2F%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.btn-del { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="24" height="24" viewBox="0 0 24 24"%3E%3Cpath fill="%232685b5" d="m18 9l-5-5v3q0 .825.588 1.413T15 9h3Zm0 10.425L16.6 20.8q-.275.275-.688.288T15.2 20.8q-.275-.275-.275-.7t.275-.7l1.4-1.4l-1.4-1.4q-.275-.275-.275-.7t.275-.7q.275-.275.7-.275t.7.275l1.4 1.4l1.4-1.4q.275-.275.688-.287t.712.287q.275.275.275.7t-.275.7L19.425 18l1.375 1.4q.275.275.288.688t-.288.712q-.275.275-.7.275t-.7-.275L18 19.425ZM6 22q-.825 0-1.413-.588T4 20V4q0-.825.588-1.413T6 2h7.175q.4 0 .763.15t.637.425l4.85 4.85q.275.275.425.638t.15.762v3.525q-.475-.175-.988-.263T17.976 12q-2.5 0-4.237 1.738T12 17.974q0 1.125.4 2.163T13.55 22H6Z"%2F%3E%3C%2Fsvg%3E') center no-repeat !important; +} + +.btn-del-all { + background: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="24" height="24" viewBox="0 0 24 24"%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cpath d="M24 0v24H0V0h24ZM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018Zm.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022Zm-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01l-.184-.092Z"%2F%3E%3Cpath fill="%232685b5" d="M4 3a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V7.5a2 2 0 0 0-2-2h-7.52l-1.399-1.75A2 2 0 0 0 9.52 3H4Zm5.172 7.172a1 1 0 0 1 1.414 0L12 11.586l1.414-1.414a1 1 0 1 1 1.414 1.414L13.414 13l1.414 1.414a1 1 0 0 1-1.414 1.414L12 14.414l-1.414 1.414a1 1 0 1 1-1.414-1.414L10.586 13l-1.414-1.414a1 1 0 0 1 0-1.414Z"%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E') center no-repeat !important; +} + + +.tooltip-btn, .audio-btn .sm.secondary, .audio-btn .sm.tertiary { + position: relative; + display: inline-block; + padding: 10px 20px; + border: 1px solid #ddd; + background-color: #f9f9f9; + cursor: pointer; +} + +.tooltip-btn::after, +.tooltip-btn::before, +.audio-btn .sm.secondary::after, +.audio-btn .sm.secondary::before, +.audio-btn .sm.tertiary::after, +.audio-btn .sm.tertiary::before { + content: ""; + position: absolute; + visibility: hidden; + top: 100%; + left: 50%; + transform: translateX(-50%); + transition: opacity 0.3s; + pointer-events: none; +} + +.tooltip-content-send::after { + content: "Send message"; +} + +.tooltip-content-record::after, .audio-btn .sm.secondary::after { + content: "Use microphone"; +} + +.audio-btn .sm.tertiary::after { + content: "Stop recording"; +} + +.tooltip-content-clear::after { + content: "New topic"; +} + +.tooltip-del:after { + content: "Remove selected files"; +} + +.tooltip-del-all::after { + content: "Remove all files"; +} + +.tooltip-btn::after, .audio-btn .sm.secondary::after, .audio-btn .sm.tertiary::after { + background-color: #000; + color: #fff; + text-align: center; + font-size: 12px; + font-weight: bold; + padding: 5px; + border-radius: 6px; + z-index: 1; + white-space: nowrap; + opacity: 0; + margin-top: 10px; /* Spacing between the button and the tooltip */ +} + +.tooltip-btn::before, .audio-btn .sm.secondary::before, .audio-btn .sm.tertiary::before { + border: 5px solid transparent; + border-bottom-color: #000; /* Arrow color */ +} + +.tooltip-btn:hover::after, +.tooltip-btn:hover::before, +.audio-btn .sm.secondary:hover::after, +.audio-btn .sm.secondary:hover::before, +.audio-btn .sm.tertiary:hover::after, +.audio-btn .sm.tertiary:hover::before { + visibility: visible; + opacity: 0.8; /* Arrow and tooltip opacity */ +} + + +.btn-update-group { + display: flex; + justify-content: space-evenly; + align-items: center; + width: 100%; + padding-top: 10px; +} + +.btn-update-group.hideK { + display: none; +} + +/* user_info */ +#user_info.block { + white-space: nowrap; + position: absolute; + left: 13em; + top: -1em; + z-index: var(--layer-2); + box-shadow: var(--block-shadow); + border: none !important; + border-radius: 10px 10px 10px 0; + background: var(--color-accent); + padding: var(--block-label-padding); + font-size: var(--block-label-text-size); + line-height: var(--line-sm); + width: auto; + max-height: 30px !important; + opacity: 1; + transition: opacity 0.3s ease-in-out; +} + +#user_info.block .wrap { + opacity: 0; +} + +#user_info p { + color: white; + font-weight: var(--block-label-text-weight); +} + +#user_info.hideK { + opacity: 0; + transition: opacity 1s ease-in-out; +} + +/* status_display */ +#status_display { + margin-bottom: 10px; + display: flex; + min-height: 2em; + align-items: flex-end; + justify-content: flex-end; +} + +#status_display p { + font-size: .85em; + font-family: ui-monospace, "SF Mono", "SFMono-Regular", "Menlo", "Consolas", "Liberation Mono", "Microsoft Yahei UI", "Microsoft Yahei", monospace; + color: var(--body-text-color-subdued); +} + +#status_display { + transition: all 0.6s; +} + +#chuanhu_chatbot { + transition: height 0.3s ease; +} + +/* usage_display */ +.insert_block { + position: relative; + margin: 0; + padding: 8px 12px; + box-shadow: var(--block-shadow); + border-width: var(--block-border-width); + border-color: var(--block-border-color); + border-radius: var(--block-radius); + background: var(--block-background-fill); + width: 100%; + line-height: var(--line-sm); + min-height: 2em; +} + +#usage_display p, #usage_display span { + margin: 0; + font-size: .85em; + color: var(--body-text-color-subdued); +} + +.progress-bar { + background-color: var(--input-background-fill); + margin: .5em 0 !important; + height: 20px; + border-radius: 10px; + overflow: hidden; +} + +.progress { + background-color: var(--block-title-background-fill); + height: 100%; + border-radius: 10px; + text-align: right; + transition: width 0.5s ease-in-out; +} + +.progress-text { + /* color: white; */ + display: none !important; + /*color: var(--color-accent) !important;*/ + /*font-size: 1em !important;*/ + /*font-weight: bold;*/ + /*padding-right: 10px;*/ + /*line-height: 20px;*/ +} + +/* 亮暗色模式切换 */ +#apSwitch input[type="checkbox"] { + margin: 0 !important; +} + +#apSwitch label.apSwitch { + display: flex; + align-items: center; + cursor: pointer; + color: var(--body-text-color); + font-weight: var(--checkbox-label-text-weight); + font-size: var(--checkbox-label-text-size); + line-height: var(--line-md); + margin: 2px 0 !important; +} + +input[type="checkbox"]#apSwitch_checkbox::before { + background: none !important; + content: '🌞'; + border: none !important; + box-shadow: none !important; + font-size: 22px; + top: -4.4px; + left: -1px; +} + +input:checked[type="checkbox"]#apSwitch_checkbox::before { + content: '🌚'; + left: 16px; +} + +/* .apSwitch { + top: 2px; + display: inline-block; + height: 22px; + position: relative; + width: 40px; + border-radius: 11px; + box-shadow: inset 0 0 1px 0 rgba(0,0,0,0.05), inset 0 0 2px 0 rgba(0,0,0,0.08) !important; +} +.apSwitch input { + display: none !important; +} +.apSlider { + background-color: var(--neutral-200); + bottom: 0; + cursor: pointer; + left: 0; + position: absolute; + right: 0; + top: 0; + transition: .4s; + font-size: 22px; + border-radius: 11px; +} +.apSlider::before { + transform: scale(0.9); + position: absolute; + transition: .4s; + content: "🌞"; +} +input:checked + .apSlider { + background-color: var(--primary-600); +} +input:checked + .apSlider::before { + transform: translateX(18px); + content:"🌚"; +} */ + +.switch_checkbox label { + flex-direction: row-reverse; + justify-content: space-between; +} + +.switch_checkbox input[type="checkbox"] + span { + margin-left: 0 !important; +} + +.switch_checkbox input[type="checkbox"] { + -moz-appearance: none; + appearance: none; + -webkit-appearance: none; + outline: none; +} + +.switch_checkbox input[type="checkbox"] { + display: inline-block !important; + position: relative !important; + border: none !important; + outline: none; + width: 40px !important; + height: 22px !important; + border-radius: 11px !important; + background-image: none !important; + box-shadow: inset 0 0 1px 0 rgba(0, 0, 0, 0.05), inset 0 0 2px 0 rgba(0, 0, 0, 0.08) !important; + background-color: var(--switch-checkbox-color-light) !important; + transition: .2s ease background-color; +} + +.dark .switch_checkbox input[type="checkbox"] { + background-color: var(--switch-checkbox-color-light) !important; +} + +.switch_checkbox input[type="checkbox"]::before { + content: ""; + position: absolute; + width: 22px; + height: 22px; + top: 0; + left: 0; + background: #FFFFFF; + border: 0.5px solid rgba(0, 0, 0, 0.02); + box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.15), 0 1px 0 0 rgba(0, 0, 0, 0.05); + transform: scale(0.9); + border-radius: 11px !important; + transition: .4s ease all; + box-shadow: var(--input-shadow); +} + +.switch_checkbox input:checked[type="checkbox"] { + background-color: var(--switch-checkbox-marked-color) !important; +} + +.switch_checkbox input:checked[type="checkbox"]::before { + background-color: #fff; + left: 18px; +} + +/* Override Slider Styles (for webkit browsers like Safari and Chrome) + * 好希望这份提案能早日实现 https://github.com/w3c/csswg-drafts/issues/4410 + * 进度滑块在各个平台还是太不统一了 + */ + +/* input[type="range"] { + -webkit-appearance: none; + height: 4px; + background: var(--input-background-fill); + border-radius: 5px; + background-image: linear-gradient(var(--primary-500),var(--primary-500)); + background-size: 0% 100%; + background-repeat: no-repeat; +} */ +input[type="range"] { + height: 4px; + border-radius: 5px; +} + +input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + height: 20px; + width: 20px; + border-radius: 50%; + border: solid 0.5px #ddd; + background-color: white; + cursor: ew-resize; + box-shadow: var(--input-shadow); + transition: background-color .1s ease; +} + +input[type="range"]::-webkit-slider-thumb:hover { + background: var(--neutral-50); +} + +input[type=range]::-webkit-slider-runnable-track { + -webkit-appearance: none; + box-shadow: none; + border: none; + background: transparent; +} + +hr.append-display { + margin: 8px 0; + border: none; + height: 1px; + border-top-width: 0; + background-image: linear-gradient(to right, rgba(50, 50, 50, 0.1), rgba(150, 150, 150, 0.8), rgba(50, 50, 50, 0.1)); +} + +.source-a { + font-size: 0.8em; + max-width: 100%; + margin: 0; + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + /* background-color: #dddddd88; */ + border-radius: 1.5rem; + padding: 0.2em; +} + +.source-a a, .source-a details { + display: inline-block; + background-color: #aaaaaa50; + border-radius: 1rem; + padding: 0.5em; + text-align: center; + text-overflow: ellipsis; + overflow: hidden; + min-width: 40%; + white-space: nowrap; + margin: 0.2rem 0.1rem; + text-decoration: none !important; + flex: 1; + transition: flex 0.5s; +} + +.source-a details > p { + background-color: #aaaaaa50; + border-radius: 1rem; + padding: 0.5em; + text-overflow: ellipsis; + text-align: left !important; + overflow: hidden; + white-space: pre !important; + margin: 0.2rem 0.1rem; + text-decoration: none !important; + flex: 1; + transition: flex 0.5s; +} + +.source-a a:hover, .source-a details:hover { + background-color: #aaaaaa20; + flex: 2; +} + +#submit_btn, #cancel_btn { + height: 42px !important; +} + +#submit_btn::before { + content: url("data:image/svg+xml, %3Csvg width='21px' height='20px' viewBox='0 0 21 20' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E %3Cg id='page' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E %3Cg id='send' transform='translate(0.435849, 0.088463)' fill='%23FFFFFF' fill-rule='nonzero'%3E %3Cpath d='M0.579148261,0.0428666046 C0.301105539,-0.0961547561 -0.036517765,0.122307382 0.0032026237,0.420210298 L1.4927172,18.1553639 C1.5125774,18.4334066 1.79062012,18.5922882 2.04880264,18.4929872 L8.24518329,15.8913017 L11.6412765,19.7441794 C11.8597387,19.9825018 12.2370824,19.8832008 12.3165231,19.5852979 L13.9450591,13.4882182 L19.7839562,11.0255541 C20.0619989,10.8865327 20.0818591,10.4694687 19.7839562,10.3105871 L0.579148261,0.0428666046 Z M11.6138902,17.0883151 L9.85385903,14.7195502 L0.718169621,0.618812241 L12.69945,12.9346347 L11.6138902,17.0883151 Z' id='shape'%3E%3C/path%3E %3C/g%3E %3C/g%3E %3C/svg%3E"); + height: 21px; +} + +#cancel_btn::before { + content: url("data:image/svg+xml,%3Csvg width='21px' height='21px' viewBox='0 0 21 21' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E %3Cg id='pg' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E %3Cpath d='M10.2072007,20.088463 C11.5727865,20.088463 12.8594566,19.8259823 14.067211,19.3010209 C15.2749653,18.7760595 16.3386126,18.0538087 17.2581528,17.1342685 C18.177693,16.2147282 18.8982283,15.1527965 19.4197586,13.9484733 C19.9412889,12.7441501 20.202054,11.4557644 20.202054,10.0833163 C20.202054,8.71773046 19.9395733,7.43106036 19.4146119,6.22330603 C18.8896505,5.01555169 18.1673997,3.95018885 17.2478595,3.0272175 C16.3283192,2.10424615 15.2646719,1.3837109 14.0569176,0.865611739 C12.8491633,0.34751258 11.5624932,0.088463 10.1969073,0.088463 C8.83132146,0.088463 7.54636692,0.34751258 6.34204371,0.865611739 C5.1377205,1.3837109 4.07407321,2.10424615 3.15110186,3.0272175 C2.22813051,3.95018885 1.5058797,5.01555169 0.984349419,6.22330603 C0.46281914,7.43106036 0.202054,8.71773046 0.202054,10.0833163 C0.202054,11.4557644 0.4645347,12.7441501 0.9894961,13.9484733 C1.5144575,15.1527965 2.23670831,16.2147282 3.15624854,17.1342685 C4.07578877,18.0538087 5.1377205,18.7760595 6.34204371,19.3010209 C7.54636692,19.8259823 8.83475258,20.088463 10.2072007,20.088463 Z M10.2072007,18.2562448 C9.07493099,18.2562448 8.01471483,18.0452309 7.0265522,17.6232031 C6.03838956,17.2011753 5.17031614,16.6161693 4.42233192,15.8681851 C3.6743477,15.1202009 3.09105726,14.2521274 2.67246059,13.2639648 C2.25386392,12.2758022 2.04456558,11.215586 2.04456558,10.0833163 C2.04456558,8.95104663 2.25386392,7.89083047 2.67246059,6.90266784 C3.09105726,5.9145052 3.6743477,5.04643178 4.42233192,4.29844756 C5.17031614,3.55046334 6.036674,2.9671729 7.02140552,2.54857623 C8.00613703,2.12997956 9.06463763,1.92068122 10.1969073,1.92068122 C11.329177,1.92068122 12.3911087,2.12997956 13.3827025,2.54857623 C14.3742962,2.9671729 15.2440852,3.55046334 15.9920694,4.29844756 C16.7400537,5.04643178 17.3233441,5.9145052 17.7419408,6.90266784 C18.1605374,7.89083047 18.3698358,8.95104663 18.3698358,10.0833163 C18.3698358,11.215586 18.1605374,12.2758022 17.7419408,13.2639648 C17.3233441,14.2521274 16.7400537,15.1202009 15.9920694,15.8681851 C15.2440852,16.6161693 14.3760118,17.2011753 13.3878492,17.6232031 C12.3996865,18.0452309 11.3394704,18.2562448 10.2072007,18.2562448 Z M7.65444721,13.6242324 L12.7496608,13.6242324 C13.0584616,13.6242324 13.3003556,13.5384544 13.4753427,13.3668984 C13.6503299,13.1953424 13.7378234,12.9585951 13.7378234,12.6566565 L13.7378234,7.49968276 C13.7378234,7.19774418 13.6503299,6.96099688 13.4753427,6.78944087 C13.3003556,6.61788486 13.0584616,6.53210685 12.7496608,6.53210685 L7.65444721,6.53210685 C7.33878414,6.53210685 7.09345904,6.61788486 6.91847191,6.78944087 C6.74348478,6.96099688 6.65599121,7.19774418 6.65599121,7.49968276 L6.65599121,12.6566565 C6.65599121,12.9585951 6.74348478,13.1953424 6.91847191,13.3668984 C7.09345904,13.5384544 7.33878414,13.6242324 7.65444721,13.6242324 Z' id='shape' fill='%23FF3B30' fill-rule='nonzero'%3E%3C/path%3E %3C/g%3E %3C/svg%3E"); + height: 21px; +} + +/* list */ +ol:not(.options), ul:not(.options) { + padding-inline-start: 2em !important; +} + +/* 亮色(默认) */ +#chuanhu_chatbot { + background-color: var(--chatbot-background-color-light) !important; + color: var(--chatbot-color-light) !important; +} + +[data-testid = "bot"] { + background: var(--message-bot-background-color-light) !important; + box-shadow: var(--cib-shadow-card) !important; + outline: transparent solid 1px !important; +} + +[data-testid = "user"] { + background: linear-gradient(130deg, #2685b5 20%, #135a7f 77.5%) !important; + color: white !important; + box-shadow: var(--cib-shadow-card) !important; + outline: transparent solid 1px !important; +} + +/* 暗色 */ +.dark #chuanhu_chatbot { + background-color: var(--chatbot-background-color-dark) !important; + color: var(--chatbot-color-dark) !important; +} + +.dark [data-testid = "bot"] { + background-color: var(--message-bot-background-color-dark) !important; +} + +.dark [data-testid = "user"] { + background: linear-gradient(130deg, #2685b5 20%, #135a7f 77.5%) !important; +} + +/* 屏幕宽度大于等于500px的设备 */ +/* update on 2023.4.8: 高度的细致调整已写入JavaScript */ +@media screen and (min-width: 500px) { + #chuanhu_chatbot { + height: calc(100vh - 200px); + } + + #chuanhu_chatbot > .wrapper > .wrap { + max-height: calc(100vh - 200px - var(--line-sm) * 1rem - 2 * var(--block-label-margin)); + } +} + +/* 屏幕宽度小于500px的设备 */ +@media screen and (max-width: 499px) { + #chuanhu_chatbot { + height: calc(100vh - 140px); + } + + #chuanhu_chatbot > .wrapper > .wrap { + max-height: calc(100vh - 140px - var(--line-sm) * 1rem - 2 * var(--block-label-margin)); + } + + [data-testid = "bot"] { + max-width: 95% !important; + } + + #app_title h1 { + letter-spacing: -1px; + font-size: 22px; + } +} + +#chuanhu_chatbot > .wrapper > .wrap { + overflow-x: hidden; +} + +/* 对话气泡 */ +.message { + border-radius: var(--radius-xl) !important; + border: none; + padding: var(--spacing-xl) !important; + font-size: var(--message-font-size) !important; + line-height: var(--line-md) !important; + min-height: calc(var(--text-md) * var(--line-md) + 2 * var(--spacing-xl)); + min-width: calc(var(--text-md) * var(--line-md) + 2 * var(--spacing-xl)); +} + +[data-testid = "bot"] { + max-width: 85%; + border-bottom-left-radius: 0 !important; +} + +[data-testid = "user"] { + max-width: 85%; + width: auto !important; + border-bottom-right-radius: 0 !important; +} + +.message.user p { + white-space: pre-wrap; +} + +.message .user-message { + display: block; + padding: 0 !important; + white-space: pre-wrap; +} + +.message .md-message p { + margin-top: 0.6em !important; + margin-bottom: 0.6em !important; +} + +.message .md-message p:first-child { + margin-top: 0 !important; +} + +.message .md-message p:last-of-type { + margin-bottom: 0 !important; +} + +.message .md-message { + display: block; + padding: 0 !important; +} + +.message .raw-message p { + margin: 0 !important; +} + +.message .raw-message { + display: block; + padding: 0 !important; + white-space: pre-wrap; +} + +.raw-message.hideM, .md-message.hideM { + display: none; +} + +/* custom buttons */ +.chuanhu-btn { + border-radius: 5px; + color: rgba(120, 120, 120, 0.64) !important; + padding: 4px !important; + position: absolute; + right: -22px; + cursor: pointer !important; + transition: color .2s ease, background-color .2s ease; +} + +.chuanhu-btn:hover { + background-color: rgba(167, 167, 167, 0.25) !important; + color: unset !important; +} + +.chuanhu-btn:active { + background-color: rgba(167, 167, 167, 0.5) !important; +} + +.chuanhu-btn:focus { + outline: none; +} + +.copy-bot-btn { + /* top: 18px; */ + bottom: 0; +} + +.toggle-md-btn { + /* top: 0; */ + bottom: 20px; +} + +.copy-code-btn { + position: relative; + float: right; + font-size: 1em; + cursor: pointer; +} + +.message-wrap > div img { + border-radius: 10px !important; +} + +/* history message */ +.wrapper > .wrap > .history-message { + padding: 10px !important; +} + +.history-message { + /* padding: 0 !important; */ + opacity: 80%; + display: flex; + flex-direction: column; +} + +.history-message > .history-message { + padding: 0 !important; +} + +.history-message > .message-wrap { + padding: 0 !important; + margin-bottom: 16px; +} + +.history-message > .message { + margin-bottom: 16px; +} + +.wrapper > .wrap > .history-message::after { + content: ""; + display: block; + height: 2px; + background-color: var(--body-text-color-subdued); + margin-bottom: 10px; + margin-top: -10px; + clear: both; +} + +.wrapper > .wrap > .history-message > :last-child::after { + content: "仅供查看"; + display: block; + text-align: center; + color: var(--body-text-color-subdued); + font-size: 0.8em; +} + +/* 表格 */ +table { + margin: 1em 0; + border-collapse: collapse; + empty-cells: show; +} + +td, th { + border: 1.2px solid var(--border-color-primary) !important; + padding: 0.2em; +} + +thead { + background-color: rgba(175, 184, 193, 0.2); +} + +thead th { + padding: .5em .2em; +} + +.message :not(pre) code { + display: inline; + white-space: break-spaces; + font-family: var(--font-mono); + border-radius: 6px; + margin: 0 2px 0 2px; + padding: .2em .4em .1em .4em; + background-color: rgba(175, 184, 193, 0.2); +} + +/* 代码块 */ +.message pre, +.message pre[class*=language-] { + color: #fff; + overflow-x: auto; + overflow-y: hidden; + margin: .8em 1em 1em 0em !important; + padding: var(--spacing-xl) 1.2em !important; + border-radius: var(--radius-lg) !important; +} + +.message pre code, +.message pre code[class*=language-] { + color: #fff; + padding: 0; + margin: 0; + background-color: unset; + text-shadow: none; + font-family: var(--font-mono); +} + +/* 覆盖 gradio 丑陋的复制按钮样式 */ +pre button[title="copy"] { + border-radius: 5px; + transition: background-color .2s ease; +} + +pre button[title="copy"]:hover { + background-color: #333232; +} + +pre button .check { + color: #fff !important; + background: var(--neutral-950) !important; +} + +/* 覆盖prism.css */ +.language-css .token.string, +.style .token.string, +.token.entity, +.token.operator, +.token.url { + background: none !important; +} + +.label.svelte-13hsdno.svelte-13hsdno.svelte-13hsdno { + display: none; +} + +.gallery.svelte-13hsdno.svelte-13hsdno.svelte-13hsdno { + justify-content: flex-end; +} + +.button-group { + width: 200px !important; + display: flex !important; + justify-content: space-between !important; +} + +.chatbot { + background: none !important; + border: none !important; +} + +button[class^="svelte-"], button[class*="svelte-"].selected { + width: calc(var(--size-full) / 3) !important; /* number of elements */ + background: none !important; +} + +/*#component-2 {*/ +/* gap: 0 !important;*/ +/* margin-bottom: 3px !important;*/ +/*}*/ + +.token, .token > span { + text-overflow: ellipsis; + overflow: hidden; +} + +.audio-btn > div[class^="svelte-"], .audio-btn > audio { + display: none; +} + +div.logo { + background: url('https://i.ibb.co/BnmxGhz/logo.png') no-repeat left center; + background-size: contain; + height: 40px; + align-items: flex-start; + justify-content: flex-start; +} + +#component-29 { + font-size: var(--message-font-size) !important; + box-shadow: var(--cib-shadow-card) !important; + outline: transparent solid 1px !important; +} + +#component-26 > div.gallery.svelte-13hsdno > button > div { + background: var(--chatbot-background-color-light) !important; +} + +.dark #component-26 > div.gallery.svelte-13hsdno > button > div { + background: var(--chatbot-background-color-dark) !important; +} + +.message.pending { + background: none !important; +} + +#component-36 > label { + width: inherit; +} \ No newline at end of file diff --git a/custom_vectordb.py b/custom_vectordb.py new file mode 100644 index 0000000000000000000000000000000000000000..fa90bed0fffa000fa52fc78e065805e522017b4e --- /dev/null +++ b/custom_vectordb.py @@ -0,0 +1,421 @@ +"""Wrapper around Pinecone vector database.""" +from __future__ import annotations + +import logging +import uuid +from typing import Any, Callable, Iterable, List, Optional, Tuple + +import numpy as np + +from langchain.docstore.document import Document +from langchain.embeddings.base import Embeddings +from langchain.vectorstores.base import VectorStore +from langchain.vectorstores.utils import DistanceStrategy, maximal_marginal_relevance + +logger = logging.getLogger(__name__) + + +class Pinecone(VectorStore): + """Wrapper around Pinecone vector database. + + To use, you should have the ``pinecone-client`` python package installed. + + Example: + .. code-block:: python + + from langchain.vectorstores import Pinecone + from langchain.embeddings.openai import OpenAIEmbeddings + import pinecone + + # The environment should be the one specified next to the API key + # in your Pinecone console + pinecone.init(api_key="***", environment="...") + index = pinecone.Index("langchain-demo") + embeddings = OpenAIEmbeddings() + vectorstore = Pinecone(index, embeddings.embed_query, "text") + """ + + def __init__( + self, + index: Any, + embedding_function: Callable, + text_key: str, + namespace: Optional[str] = None, + distance_strategy: Optional[DistanceStrategy] = DistanceStrategy.COSINE, + ): + """Initialize with Pinecone client.""" + try: + import pinecone + except ImportError: + raise ValueError( + "Could not import pinecone python package. " + "Please install it with `pip install pinecone-client`." + ) + if not isinstance(index, pinecone.index.Index): + raise ValueError( + f"client should be an instance of pinecone.index.Index, " + f"got {type(index)}" + ) + self._index = index + self._embedding_function = embedding_function + self._text_key = text_key + self._namespace = namespace + self.distance_strategy = distance_strategy + + @property + def embeddings(self) -> Optional[Embeddings]: + # TODO: Accept this object directly + return None + + def add_texts( + self, + texts: Iterable[str], + metadatas: Optional[List[dict]] = None, + ids: Optional[List[str]] = None, + namespace: Optional[str] = None, + batch_size: int = 32, + **kwargs: Any, + ) -> List[str]: + """Run more texts through the embeddings and add to the vectorstore. + + Args: + texts: Iterable of strings to add to the vectorstore. + metadatas: Optional list of metadatas associated with the texts. + ids: Optional list of ids to associate with the texts. + namespace: Optional pinecone namespace to add the texts to. + + Returns: + List of ids from adding the texts into the vectorstore. + + """ + if namespace is None: + namespace = self._namespace + # Embed and create the documents + docs = [] + ids = ids or [str(uuid.uuid4()) for _ in texts] + for i, text in enumerate(texts): + embedding = self._embedding_function(text) + metadata = metadatas[i] if metadatas else {} + metadata[self._text_key] = text + docs.append((ids[i], embedding, metadata)) + # upsert to Pinecone + self._index.upsert( + vectors=docs, namespace=namespace, batch_size=batch_size, **kwargs + ) + return ids + + def similarity_search_with_relevance_scores( + self, + query: str, + k: int = 4, + **kwargs: Any, + ) -> List[Tuple[Document, float]]: + return [ + a + for a in self.similarity_search_with_score(query, k=k) + if a[1] > kwargs["score_threshold"] + ] + + def similarity_search_with_score( + self, + query: str, + k: int = 4, + filter: Optional[dict] = None, + namespace: Optional[str] = None, + ) -> List[Tuple[Document, float]]: + """Return pinecone documents most similar to query, along with scores. + + Args: + query: Text to look up documents similar to. + k: Number of Documents to return. Defaults to 4. + filter: Dictionary of argument(s) to filter on metadata + namespace: Namespace to search in. Default will search in '' namespace. + + Returns: + List of Documents most similar to the query and score for each + """ + if namespace is None: + namespace = self._namespace + query_obj = self._embedding_function(query) + docs = [] + results = self._index.query( + [query_obj], + top_k=k, + include_metadata=True, + namespace=namespace, + filter=filter, + ) + for res in results["matches"]: + metadata = res["metadata"] + if self._text_key in metadata: + text = metadata.pop(self._text_key) + score = res["score"] + docs.append((Document(page_content=text, metadata=metadata), score)) + else: + logger.warning( + f"Found document with no `{self._text_key}` key. Skipping." + ) + return docs + + def similarity_search( + self, + query: str, + k: int = 4, + filter: Optional[dict] = None, + namespace: Optional[str] = None, + **kwargs: Any, + ) -> List[Document]: + """Return pinecone documents most similar to query. + + Args: + query: Text to look up documents similar to. + k: Number of Documents to return. Defaults to 4. + filter: Dictionary of argument(s) to filter on metadata + namespace: Namespace to search in. Default will search in '' namespace. + + Returns: + List of Documents most similar to the query and score for each + """ + docs_and_scores = self.similarity_search_with_score( + query, k=k, filter=filter, namespace=namespace, **kwargs + ) + return [doc for doc, _ in docs_and_scores] + + def _select_relevance_score_fn(self) -> Callable[[float], float]: + """ + The 'correct' relevance function + may differ depending on a few things, including: + - the distance / similarity metric used by the VectorStore + - the scale of your embeddings (OpenAI's are unit normed. Many others are not!) + - embedding dimensionality + - etc. + """ + + if self.distance_strategy == DistanceStrategy.COSINE: + return self._cosine_relevance_score_fn + elif self.distance_strategy == DistanceStrategy.MAX_INNER_PRODUCT: + return self._max_inner_product_relevance_score_fn + elif self.distance_strategy == DistanceStrategy.EUCLIDEAN_DISTANCE: + return self._euclidean_relevance_score_fn + else: + raise ValueError( + "Unknown distance strategy, must be cosine, max_inner_product " + "(dot product), or euclidean" + ) + + def max_marginal_relevance_search_by_vector( + self, + embedding: List[float], + k: int = 4, + fetch_k: int = 20, + lambda_mult: float = 0.5, + filter: Optional[dict] = None, + namespace: Optional[str] = None, + **kwargs: Any, + ) -> List[Document]: + """Return docs selected using the maximal marginal relevance. + + Maximal marginal relevance optimizes for similarity to query AND diversity + among selected documents. + + Args: + embedding: Embedding to look up documents similar to. + k: Number of Documents to return. Defaults to 4. + fetch_k: Number of Documents to fetch to pass to MMR algorithm. + lambda_mult: Number between 0 and 1 that determines the degree + of diversity among the results with 0 corresponding + to maximum diversity and 1 to minimum diversity. + Defaults to 0.5. + Returns: + List of Documents selected by maximal marginal relevance. + """ + if namespace is None: + namespace = self._namespace + results = self._index.query( + [embedding], + top_k=fetch_k, + include_values=True, + include_metadata=True, + namespace=namespace, + filter=filter, + ) + mmr_selected = maximal_marginal_relevance( + np.array([embedding], dtype=np.float32), + [item["values"] for item in results["matches"]], + k=k, + lambda_mult=lambda_mult, + ) + selected = [results["matches"][i]["metadata"] for i in mmr_selected] + return [ + Document(page_content=metadata.pop((self._text_key)), metadata=metadata) + for metadata in selected + ] + + def max_marginal_relevance_search( + self, + query: str, + k: int = 4, + fetch_k: int = 20, + lambda_mult: float = 0.5, + filter: Optional[dict] = None, + namespace: Optional[str] = None, + **kwargs: Any, + ) -> List[Document]: + """Return docs selected using the maximal marginal relevance. + + Maximal marginal relevance optimizes for similarity to query AND diversity + among selected documents. + + Args: + query: Text to look up documents similar to. + k: Number of Documents to return. Defaults to 4. + fetch_k: Number of Documents to fetch to pass to MMR algorithm. + lambda_mult: Number between 0 and 1 that determines the degree + of diversity among the results with 0 corresponding + to maximum diversity and 1 to minimum diversity. + Defaults to 0.5. + Returns: + List of Documents selected by maximal marginal relevance. + """ + embedding = self._embedding_function(query) + return self.max_marginal_relevance_search_by_vector( + embedding, k, fetch_k, lambda_mult, filter, namespace + ) + + @classmethod + def from_texts( + cls, + texts: List[str], + embedding: Embeddings, + metadatas: Optional[List[dict]] = None, + ids: Optional[List[str]] = None, + batch_size: int = 32, + text_key: str = "text", + index_name: Optional[str] = None, + namespace: Optional[str] = None, + upsert_kwargs: Optional[dict] = None, + **kwargs: Any, + ) -> Pinecone: + """Construct Pinecone wrapper from raw documents. + + This is a user friendly interface that: + 1. Embeds documents. + 2. Adds the documents to a provided Pinecone index + + This is intended to be a quick way to get started. + + Example: + .. code-block:: python + + from langchain import Pinecone + from langchain.embeddings import OpenAIEmbeddings + import pinecone + + # The environment should be the one specified next to the API key + # in your Pinecone console + pinecone.init(api_key="***", environment="...") + embeddings = OpenAIEmbeddings() + pinecone = Pinecone.from_texts( + texts, + embeddings, + index_name="langchain-demo" + ) + """ + try: + import pinecone + except ImportError: + raise ValueError( + "Could not import pinecone python package. " + "Please install it with `pip install pinecone-client`." + ) + + indexes = pinecone.list_indexes() # checks if provided index exists + + if index_name in indexes: + index = pinecone.Index(index_name) + elif len(indexes) == 0: + raise ValueError( + "No active indexes found in your Pinecone project, " + "are you sure you're using the right API key and environment?" + ) + else: + raise ValueError( + f"Index '{index_name}' not found in your Pinecone project. " + f"Did you mean one of the following indexes: {', '.join(indexes)}" + ) + for i in range(0, len(texts), batch_size): + # set end position of batch + i_end = min(i + batch_size, len(texts)) + # get batch of texts and ids + lines_batch = texts[i:i_end] + # create ids if not provided + if ids: + ids_batch = ids[i:i_end] + else: + ids_batch = [str(uuid.uuid4()) for n in range(i, i_end)] + # create embeddings + embeds = embedding.embed_documents(lines_batch) + # prep metadata and upsert batch + if metadatas: + metadata = metadatas[i:i_end] + else: + metadata = [{} for _ in range(i, i_end)] + for j, line in enumerate(lines_batch): + metadata[j][text_key] = line + to_upsert = zip(ids_batch, embeds, metadata) + # upsert to Pinecone + _upsert_kwargs = upsert_kwargs or {} + index.upsert(vectors=list(to_upsert), namespace=namespace, **_upsert_kwargs) + return cls(index, embedding.embed_query, text_key, namespace, **kwargs) + + @classmethod + def from_existing_index( + cls, + index_name: str, + embedding: Embeddings, + text_key: str = "text", + namespace: Optional[str] = None, + ) -> Pinecone: + """Load pinecone vectorstore from index name.""" + try: + import pinecone + except ImportError: + raise ValueError( + "Could not import pinecone python package. " + "Please install it with `pip install pinecone-client`." + ) + + return cls( + pinecone.Index(index_name), embedding.embed_query, text_key, namespace + ) + + def delete( + self, + ids: Optional[List[str]] = None, + delete_all: Optional[bool] = None, + namespace: Optional[str] = None, + filter: Optional[dict] = None, + **kwargs: Any, + ) -> None: + """Delete by vector IDs or filter. + Args: + ids: List of ids to delete. + filter: Dictionary of conditions to filter vectors to delete. + """ + + if namespace is None: + namespace = self._namespace + + if delete_all: + self._index.delete(delete_all=True, namespace=namespace, **kwargs) + elif ids is not None: + chunk_size = 1000 + for i in range(0, len(ids), chunk_size): + chunk = ids[i : i + chunk_size] + self._index.delete(ids=chunk, namespace=namespace, **kwargs) + elif filter is not None: + self._index.delete(filter=filter, namespace=namespace, **kwargs) + else: + raise ValueError("Either ids, delete_all, or filter must be provided.") + + return None diff --git a/data.json b/data.json index 9b2458050f4ccfcbc3bb737f7864e5b545d36a86..73107e309a8c9e1bb796fb93c6a95b4a93e98f6d 100644 --- a/data.json +++ b/data.json @@ -1 +1 @@ -"{\"pfbid0bL6K1WG4WksXbC2rN4xzUnnNTTXeiv87rJyZSQCSF95wKfqQ3XAVWaRKbV5E7Ptil\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 8, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 8, \"comments\": 1, \"content\": \"AMARAN RIBUT PETIR. Ribut petir, hujan lebat dan angin kencang dijangka di negeri Perlis \u2022 Kedah (Langkawi, Kubang Pasu, Kota Setar dan Padang Terap) \u2022 Pulau Pinang \u2022 Terengganu (Besut, Setiu, Kuala Nerus dan Kuala Terengganu) sehingga 4:00 petang; Rabu, 26 Julai 2023.Amaran dikeluarkan apabila terdapat tanda-tanda menunjukkan ribut petir dengan intensiti hujan melebihi 20 mm/jam yang hampir ATAU dijangka berlaku melebihi sejam. Amaran ribut petir adalah amaran jangka pendek yang sah dalam tempoh tidak melebihi enam jam untuk satu-satu keluaran.Dikeluarkan pada: 1:25 tengah hari, 26 Julai 2023#ributpetirmetmalaysia#metmalaysia#NRECC#MalaysiaMADANI\", \"posted_on\": \"2023-07-26T12:58:19.905715\", \"video\": [], \"image\": [\"https://scontent.fsgn2-8.fna.fbcdn.net/v/t39.30808-6/362914619_677866284383689_33145274970187979_n.jpg?stp=dst-jpg_p180x540&_nc_cat=102&ccb=1-7&_nc_sid=730e14&_nc_ohc=AcndcfG_n1YAX_HIiLt&_nc_ht=scontent.fsgn2-8.fna&oh=00_AfCkYSj5ycx5NfloaoYBrW36iOfS6wDzF4JieUPENxVy8w&oe=64C5E08C\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0bL6K1WG4WksXbC2rN4xzUnnNTTXeiv87rJyZSQCSF95wKfqQ3XAVWaRKbV5E7Ptil?__cft__[0]=AZXxrrcdLEIFgRlM0QT4J_sr1nDzaJa5s5iBnAc0kZsacRt7UhHugMUG1RV-HOX6gcMuwTKFXwTgRRESYATnLvK-gjp1dB-wSPPltOtZ9u9J_t4NMriCv2A8cb7UWEmWL3rm4pCFRw31vva5sF7gPXDUlmRM6YH20ikbfVA0PUUJ-x3xUXxSw5AKv7KakA5OgCIoplRHyh1rg7IDcU4gtpu_pef6ZQWazgdoQvPXKi-Z8r_LrUp6TtYEZu4K2k_aP6s&__tn__=%2CO%2CP-R\"}, \"pfbid0trQFPXpjvP5wBYLKaCCJ5CMSvzJMzLwc4gApwhnepaEj67XSpo5AFTfwexNsPBzLl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 7, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 7, \"comments\": 1, \"content\": \"SESI JENDELA PELANGGAN MBPPAnda dialu-alukan untuk menyertai Sesi Jendela Pelanggan pada 27 Julai 2023 (Khamis) bagi mengajukan sebarang aduan, pertanyaan ataupun cadangan kepada kami.Sila daftar pada pautan ini selewat-lewatnya pada 26 Julai 2023 (Rabu) jam 4.30 petang dan pihak urusetia akan menghubungi anda. https://forms.gle/Pn9SBHBeHC4j3up56#jendelapelanggan#bilangan07#aduanmbpp#mbpp\", \"posted_on\": \"2023-07-26T09:58:25.356447\", \"video\": [], \"image\": [\"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/362922220_701092018729018_2536095607797190940_n.jpg?stp=dst-jpg_p180x540&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=zmchy6xDUrcAX8Sx-p-&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfCloGPgFHMuWyAZsWG36ahDRJUV9ZkM5_DPPtAKgylM4Q&oe=64C5E5DE\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0trQFPXpjvP5wBYLKaCCJ5CMSvzJMzLwc4gApwhnepaEj67XSpo5AFTfwexNsPBzLl?__cft__[0]=AZUyMXgb-borS8E3PmF2F-f1z6rnhUtnCKrVDgqpQ1nZPY4s0IUD2ICSznn-Afl_mhp3QEUF4oC1rzsHVVs4SI-9NJ5XJUeA5SpFYqU9Nl4AohyVhGDz_A6_XcWVJRd3vfZz0ak770MRrZZ6iNcRfVkzNvOsG9HrVs_zbRDk1TqxFU1Lpr1qofYCPaRNWAd_XRRXlve5gJNl2oe65kqpd0_4&__tn__=%2CO%2CP-R\"}, \"pfbid0RYJrNbkg5cC53f5sLgUAMZgbZDRPcYJADvLy7MeVcm2eYRQZ2RCp9Km1b1EREhTXl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 20, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 20, \"comments\": 2, \"content\": \"DATUK BANDAR MBPP TERIMA KUNJUNGAN HORMAT DELEGASI PERTUBUHAN ARKITEK MALAYSIA,NORTHERN CHAPTER25 Julai 2023YBhg. Dato' Ir. Rajendran a/l P. Anthony, Datuk Bandar Majlis Bandaraya Pulau Pinang amat berbesar hati dan mengalu-alukan kunjungan hormat Dato' Ar. Loh Chiak Eong, Presiden Pertubuhan Arkitek Malaysia, Northern Chapter bersama barisan delegasi. Pertemuan yang amat bermakna hari ini membincangkan hala tuju serta kerjasama strategik yang diangkat bersama dalam mempertingkatkan kualiti taraf hidup penduduk di Pulau Pinang selaras dengan visi Kerajaan Negeri Pulau Pinang. Pertemuan yang telah diadakan bertempat di Bilik Perdana Majlis Bandaraya Pulau Pinang Aras 4, KOMTAR, Pulau Pinang turut dihadiri Pengarah Kawalan Bangunan - Encik Rizuwan Salleh, Pengarah Perancangan Pembangunan - Tpr. Mohd Bashir Bin Sulaiman, Pengarah Konservasi Warisan - Puan Lee Tit Kun, Timbalan Pengarah Kejuruteraan - Encik Zainuddin Bin Mohd Shariff, Ketua Arkitek - Encik Tan Lin Hai dan Arkitek Landskap - Puan Hajah Nor Rezan Binti Sulaiman.\", \"posted_on\": \"2023-07-25T17:58:25.527738\", \"video\": [], \"image\": [\"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/361589801_700647228773497_3360174847855652712_n.jpg?stp=dst-jpg_p526x395&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=OcNb7qO8GDsAX848AOj&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfBkqTAbtQ-ammOujDS2dAhe8oTL41OXQ1U2TKQeewoMzA&oe=64C56E99\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362618945_700647278773492_5015617466471678597_n.jpg?stp=dst-jpg_p526x395&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=n4ToAYkB_jkAX-REa_n&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfDDM5eBqbyxjhi7KNV6M-uFRRJ2TjWqU-tJEiDR2PdrVg&oe=64C69C8D\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362688960_700647302106823_966226846173849865_n.jpg?stp=dst-jpg_p526x395&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=nrKpXXTUGf8AX_-Yi95&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfApmzE8SdcMwG8Ht7OokWcawbYTEEgigFdyHEu4L0fWHA&oe=64C651C5\", \"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/361583990_700647318773488_2904764889062170237_n.jpg?stp=dst-jpg_p526x395&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=8UPm0AK0tBwAX83rJZX&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfAuHGVpeTr4QblrQAPFp6Kdv5b1Bhg7vRbQXgf4R6NMaw&oe=64C6D33F\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/361615395_700647342106819_5776684050650670196_n.jpg?stp=dst-jpg_s600x600&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=Aov6JS5rbbQAX9C-npi&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfD6W5q356V05645Uomy8q4E6hEA2CIZS_eFsUgW9Nj9Dg&oe=64C65766\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0RYJrNbkg5cC53f5sLgUAMZgbZDRPcYJADvLy7MeVcm2eYRQZ2RCp9Km1b1EREhTXl?__cft__[0]=AZWkpcf0Nln3YZ_mXvdqw5AGLBiXgFTC4CL2h3KhCuhhgxXpYIP5Enhf9QBNFnXjmD51txDq2cMm3ZkjWDB3Uq3IErctGLAwii_66F_-DbIVQIOhkRMGiQTuuyoqRu0dnY6ZCzF6ff9pBl6BVn61zjRAlYUkbOAWbi0s-BqO1jD4607eMwjhjd_j1QfkcLyWWl2ICP0pSeE-keA5AZMBLnfI&__tn__=%2CO%2CP-R\"}, \"pfbid02kkoBrqZgVy9iJ2A6LaMxptTNqBh9AGZeXGKnYU5LmP3xTLw71UsgYZMTA3YPPn8Al\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 13, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 13, \"comments\": 25, \"content\": \"MAKLUMAN UMUM PENUTUPAN SEMENTARA SEBAHAGIAN JALAN PERAK (PERSIMPANGAN ANTARA JALAN PANGKOR, LEBUHRAYA PEEL DAN JALAN PERAK)DAERAH TIMUR LAUT PULAU PINANG#maklumanumum#penutupansementara#jalanpangkor\", \"posted_on\": \"2023-07-25T17:58:25.737254\", \"video\": [], \"image\": [\"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/361885206_700528988785321_430392079782812923_n.jpg?stp=dst-jpg_p417x417&_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=5VHlLoiZaNMAX9joHGW&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfAIhTa1sIAeR7fNPZBvN8FvOlE8w9jYIOholMBXTehuvQ&oe=64C58F8C\", \"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/361950036_700529002118653_2056017328874695579_n.jpg?stp=dst-jpg_p552x414&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=YoZyyhAixtoAX_pK_QB&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfB_f9d8gdok8Ggom_KZ5rLpTjDWpZnU07i7pEFHsqtRKw&oe=64C5D856\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362666857_700529028785317_3669243307978518231_n.jpg?stp=dst-jpg_p552x414&_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=cieIIntRj0YAX8H1wni&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfCvfjDY1YBQz3nAM8KHrUdHGUmAsh6ZxyTwr94y58Ol3A&oe=64C6C145\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/361940891_700529045451982_8224188709230313821_n.jpg?stp=dst-jpg_p417x417&_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=BwzTcA4FRxoAX8azMwD&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfCNYkpj2bgdvqEJ1WPBlBZ6PotqcTCyDsH68pHT1qC_wg&oe=64C61CD4\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02kkoBrqZgVy9iJ2A6LaMxptTNqBh9AGZeXGKnYU5LmP3xTLw71UsgYZMTA3YPPn8Al?__cft__[0]=AZXBrIIGxpfal3Z0luNHoIVLu2KAFlza75XJcyxTDm97S6OLZ79RJOTYZ_aGf-xCl9I39ghWDtdj4TkoiarAJSBPnAKEzKJmksvEPQtDdi0XuQof0RAGSjJiN9sk-pOGchJMWTFJ9AI3TdnsF3Nc5K3RRTmYCS0fyZDTBeeekThuewh7vn8VM2b6_66DaQD97sXpW53OPGq9gDsKcwlhnRIY&__tn__=%2CO%2CP-R\"}, \"pfbid03F3SdqpeAkehQaJKfzBLWhxpqfxgt2GgibaBRU1Y25uS9rsTN52fwJedxpP6yx7fl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 25, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 25, \"comments\": 9, \"content\": \"KENYATAAN MEDIAPENGOPERASIAN BANGUNAN TEMPAT LETAK KERETA BERTINGKAT DI BELAKANG PASAR AWAM BATU LANCANG, BANDAR JELUTONG, DAERAH TIMUR LAUT, PULAU PINANG.24 Julai 2023Majlis Bandaraya Pulau Pinang (MBPP) ingin memaklumkan bahawa Bangunan Tempat Letak Kereta Bertingkat di belakang Pasar Awam Batu Lancang akan dibuka kepada orang awam mulai 25 Julai 2023 (Selasa), jam 8:00 pagi. Bangunan Tempat Letak Kereta tersebut akan beroperasi secara 24 jam. Bangunan enam tingkat ini yang mempunyai 223 petak tempat letak kereta akan dibuka kepada orang ramai secara PERCUMA sehingga ke satu tarikh yang akan dimaklumkan kelak. Orang awam boleh mengakses bangunan tersebut dari belakang Pasar Batu Lancang.Pembukaan Bangunan Tempat Letak Kereta tersebut dijangka dapat menampung keperluan orang ramai terutamanya dalam permasalahan kekurangan petak letak kereta di kawasan sekitar Pasar Awam Batu Lancang. MBPP berharap agar orang awam, terutamanya pengguna dapat memberi kerjasama dalam mengguna dan menjaga kemudahan yang disediakan.Sekian, terima kasih.Dikeluarkan oleh :Bahagian Komunikasi Korporat dan Perhubungan Awam,Jabatan Pengurusan Korporat dan Komuniti,Majlis Bandaraya Pulau PinangBertarikh : 24 Julai 2023\", \"posted_on\": \"2023-07-25T17:58:32.216849\", \"video\": [], \"image\": [\"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/362684071_700112485493638_6490033210307187634_n.jpg?stp=dst-jpg_s720x720&_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=jfOYM2GPBCsAX8_KGLD&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfDlW55FWBmCQTJj-tWX1reHvXJYp0xLRykOYBZvR5WDYg&oe=64C571E5\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid03F3SdqpeAkehQaJKfzBLWhxpqfxgt2GgibaBRU1Y25uS9rsTN52fwJedxpP6yx7fl?__cft__[0]=AZVZ0UKFQGKE9dO0rwTpBbbbi9oWuSl2ccVVWIPwL9U0K2736YOJG-znfXBVkEBrKPrL1GwKSjF6ONsPOGkhx2rsuRTo4ZEr33yLKmixqW1zb6rVjzdikcRbheqXFbxOvKrSPyHEK7_XhYjB8rD7sDqe7qPot_rMW26mSHSK4b3F9X8CZy0iNtWREWpzxLjVylRGYi7k4EQoXXDWgUU46bFW&__tn__=%2CO%2CP-R\"}, \"pfbid02EigDvePjJuyhwmiFn8N625wpNX3h5sHWnaVFwoJC2GALZR5THuwSWiaZKKCyspz2l\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 29, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 29, \"comments\": 2, \"content\": \"SETIAUSAHA BANDARAYA DAN AHLI MAJLIS MBPP MENYANTUNI KELUARGA MANGSA AKIBAT KEMALANGAN POKOK TUMBANG24 Julai 2023Majlis Bandaraya Pulau Pinang yang diwakili YBrs. Sr. Cheong Chee Hong, Setiausaha Bandaraya bersama Ahli Majlis Encik Quah Boon Lim serta barisan ketua-ketua jabatan dengan perasaan rendah diri hari ini telah menziarahi seorang mangsa yang terlibat dalam kemalangan akibat pokok tumbang dan menghempap bahagian di belakang rumah mangsa. Kejadian tersebut berpunca akibat hujan lebat serta angin kencang yang berlaku pada awal pagi Sabtu yang lalu (22 Julai 2023) dan dilaporkan sebanyak dua buah rumah di kawasan Lintang Delima telah mengalami kerosakan. Susulan itu, mangsa yang cedera telah dibawa oleh ahli keluarga ke hospital untuk menerima rawatan sewajarnya di sebuah hospital swasta.Majlis Bandaraya Pulau Pinang menzahirkan rasa simpati dan takziah kepada seluruh keluarga mangsa yang terlibat di samping akan menyalurkan sumbangan wang tunai bagi membantu meringankan beban kos pembaikan.\", \"posted_on\": \"2023-07-24T17:58:32.390422\", \"video\": [], \"image\": [\"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/362683530_700028038835416_7605803971882575798_n.jpg?stp=dst-jpg_s600x600&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=KUUzkrq69zMAX-pcUbN&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfD-wkzDGhyLFtU5ExS6OfKVCp6SNw4tFgQiN-rZuSDu2Q&oe=64C69AFC\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/361202440_700028075502079_1534549892103331750_n.jpg?stp=dst-jpg_s600x600&_nc_cat=106&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qPz6XdivpiIAX8fymT3&_nc_oc=AQn4YYqTP1xb0KllsIHI-8cLN1s346Q8ZV41s1gzhuIf-neBKs3k3CWgiuiClzTJeS4&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfB1J49Kae6v8BfeCbnF_Y0jTrjfDnsqAGTLspVPOVILwA&oe=64C64CF3\", \"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/361282688_700028095502077_4816978841061704015_n.jpg?stp=dst-jpg_s600x600&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=kbDIaz7HuzoAX-7Clyl&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfD8Z5ctqQGazoIaX2q4D9EtA2C2T397wQLpbdGSqkgcAg&oe=64C64D16\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362681824_700028112168742_1173937444798386479_n.jpg?stp=dst-jpg_s600x600&_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=k0q2xsg8qzMAX-mhPKP&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfCjNSEuwOORE-GHP_51RWBoO69Dbtv8CqcMazj8ohpTug&oe=64C502C9\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02EigDvePjJuyhwmiFn8N625wpNX3h5sHWnaVFwoJC2GALZR5THuwSWiaZKKCyspz2l?__cft__[0]=AZUTiK34Fwdcli7Vms2WqNXc0PpwU48tjm5uoruT7_aaSlt-b5Fwd4dcdFkEtLX6Md6P7dJQWmppPJyOdo6IGtPM_wWGEMJ_W7cy30bFF4vLI7s-aCwdYnANWuCk6QD0FzBH-EQdNklxTI78i3I7yICbcIFiavJIxK7mYMK2Yn2oQtYaEbDSMYt7URuItNZmxuP8gzAb52OwqdIy5V647ni2&__tn__=%2CO%2CP-R\"}, \"pfbid02LZEE49iB6R4miMgufE7FCPM3SAKH92m3r4UjPV78R2FQEusEdCRdrQrAg8s8Pdd9l\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 2, \"reactions\": {\"likes\": 63, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 63, \"comments\": 1, \"content\": \"PROGRAM PENANAMAN BAKAU PERINGKAT MAJLIS BANDARAYA PULAU PINANG BAGI TAHUN 2023 DI KAWASAN PAYA BAKAU HUTAN SIMPAN BALIK PULAU 23 JULAI 2023Majlis Bandaraya Pulau Pinang merakamkan setinggi-tinggi penghargaan dan jutaan terima kasih kepada YB Tuan Jagdeep Singh Deo a/l Karpal Singh, EXCO Perumahan, Kerajaan Tempatan dan Perancangan Bandar dan Desa yang telah menyempurnakan Program Penanaman Bakau Peringkat Majlis Bandaraya Pulau Pinang Bagi Tahun 2023 yang diadakan hari ini bertempat di kawasan paya bakau Hutan Simpan Balik Pulau (Jalan Baru Sungai Kongsi). Majlis Bandaraya Pulau Pinang telah menyediakan sebanyak 1,300 batang anak pokok bakau spesis api-api manakala pihak Exabytes Group/EasyParcel telah menyumbang 1,000 batang anak pokok bakau dan Jabatan Perhutanan Negeri Pulau Pinang turut menyumbang sebanyak 1,000 batang anak pokok bakau.Sejak tahun 2018 sehingga Jun 2023, Majlis Bandaraya Pulau Pinang telah menanam sebanyak 88,350 pokok di seluruh kawasan pulau, Pulau Pinang dan pada hari ini ditambah lagi dengan penanaman sebanyak 3,300 batang anak pokok bakau.Keseluruhan jumlah pokok yang ditanam di Pulau Pinang telah mencapai jumlah sebanyak 442,936 pokok sejak 2008. Agenda hijau ini akan teruskan sehingga mencapai sasaran 500,000 pokok di tanam di seluruh negeri sebagai salah satu langkah persediaan Pulau Pinang mengawal peningkatan mendadak perubahan iklim. Hadir pada program hijau ini adalah YBhg. Dato' Ir. Rajendran a/l P. Anthony, Datuk Bandar bersama barisan Ahli Majlis-Ahli Majlis, YBrs. Sr. Cheong Chee Hong, Setiausaha Bandaraya, ketua-ketua jabatan, para pegawai dan wira-wira baju hijau Majlis Bandaraya Pulau Pinang. Turut hadir pada program ini adalah wakil dari pihak penaja iaitu Cik Lim Ying Hwa - Corporate Legal Manager of Exabytes Group dan Encik Joseph Chew Chin MengMarketing Team Lead of EasyParcel. Manakala Encik Ir. Dzulhilmi bin Zulkifli, Jurutera Awam yang mewakili Jabatan Kerja Raya, Cawangan Jalan (Unit Projek Khas Zon Utara 3) dan pegawai Jabatan Perhutanan Negeri Pulau Pinang turut hadir memberi sokongan kepada program hari iniKerajaan Negeri Pulau Pinang menerusi Majlis Bandaraya Pulau Pinang amat mengalu-alukan penyertaan dan penglibatan lebih banyak Persatuan dan Pertubuhan Bukan Kerajaan serta jabatan-jabatan dan agensi kerajaan di seluruh kawasan Pulau Pinang bagj memperkasakan usaha untuk membendung peningkatan mendadak perubahan iklim.\", \"posted_on\": \"2023-07-23T17:58:32.569121\", \"video\": [], \"image\": [\"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/360162982_699412785563608_6841802677807497668_n.jpg?stp=dst-jpg_p526x395&_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=bWYKMdXaBZYAX9jhqnl&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfCsUrfqk83RHptZLP4l-lZ0CtRhHLkwc_lySKYK8Ap3rA&oe=64C5B149\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/361173237_699412945563592_6618748741275388125_n.jpg?stp=dst-jpg_s600x600&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=n7JlNvSP1M4AX9eaXdN&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfDxlP-m5pPoloNxAH_gFrbINcOWxC9twTXigFYB3yYMSA&oe=64C5F578\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/362646250_699412968896923_9194157420572023411_n.jpg?stp=dst-jpg_p526x395&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=R43ieVYZjOwAX_yh28G&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfDJYM298W2SpvuT5ZYGLFKCD8TpNTSg3YrZOPYw70ir1g&oe=64C521BC\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/360155689_699412988896921_7841179063496481138_n.jpg?stp=dst-jpg_p526x395&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=dOAd3tiCQZAAX_fKlWs&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfCJbll2XYN2b1iWHwQU9PqqdqHLFyc32qAAktmlTeMBeA&oe=64C59B27\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/361178340_699413002230253_9013619835535210897_n.jpg?stp=dst-jpg_p526x395&_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qd4ZoRzAZCkAX8uT-LQ&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfAQNEBhS96902Cp0l9fk8KbrVbrraMOX4Gz9vPl62rh9g&oe=64C577F3\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02LZEE49iB6R4miMgufE7FCPM3SAKH92m3r4UjPV78R2FQEusEdCRdrQrAg8s8Pdd9l?__cft__[0]=AZXX7ByUelE699FtcKWIoFCYhVpKe1MeBtuXzAssG8dfI0ELt1D8LKXOGtqmzlLsgOkHVRZTXKS7cr1sj7vtPRjMHSq6LoC32L8vHQ_rGUDwTRGwS92ppsZk52HYevLVNwW3MzPKqd6WXh9_nuEc3UMXvSIjPYrPefejV2VwFFbo6YqgOv9UzfcX8lvsiLC8ljcbRoRepWtFpRwSjEIpjVdo&__tn__=%2CO%2CP-R\"}, \"pfbid0Jufsa3DYCakcSgTKFVxQPabndEAybYJN6LwXNmwM9EUQJEujK2QYJ7HpzuABaoK7l\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 8, \"reactions\": {\"likes\": 42, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 42, \"comments\": 1, \"content\": \"PROGRAM TNR BERSAMA-\\\"SAMA\\\" TUMPU KEBAJIKAN KUCING TERBIAR DI JALANAN22 Julai 2023Prihatin terhadap kebajikan kucing-kucing yang terbiar di jalanan, penganjuran Program TNR Bersama - SAMA yang dirasmikan oleh YB Syerleena Abdul Rashid, Ahli Parlimen Bukit Bendera (Mantan Adun Seri Delima) telah membuka sebuah lembaran yang amat bermakna.Program yang diadakan di Gelanggang Bola Keranjang Island Glades bertujuan untuk membuka ruang perhatian dan kesedaran kepada orang awam terhadap usaha dan tindakan yang perlu dilaksanakan bagi menyelamatkan haiwan comel itu daripada menerima nasib malang.Sebagai Pihak Berkuasa Tempatan yang peka dan mengambil perhatian terhadap isu seumpama ini, Datuk Bandar, YBhg. Dato' Ir. Rajendran a/l P. Anthony, Datuk Bandar bersama barisan Ahli Majlis Cik Connie Tan, Encik Quah Boon Lim, Encik Rohaizat Hamid dan Cik Nurhafiza Huda Idris turut hadir sebagai sokongan penuh terhadap program ini.Majlis Bandaraya Pulau Pinang mengalu-alukan dan akan memberi sokongan kepada bukan sahaja kepada Pertubuhan SAMA - (Spay Adopt Manage Assist Society) malahan kepada semua persatuan-persatuan, pertubuhan bukan kerajaan dan agensi-agensi yang menyumbang masa, tenaga dan kepakaran serta peranan penting dalam memastikan program TNR (Trap Neuter Rehome) berjaya dilaksanakan hingga mencapai sasaran yang membanggakan.\", \"posted_on\": \"2023-07-23T17:58:39.072516\", \"video\": [], \"image\": [\"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/362638083_699005078937712_3416986764543683977_n.jpg?stp=dst-jpg_p526x395&_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=Lz-tHoUBF0wAX8J7ibR&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfAG2KtNAjNJKSKpTHaFebrysJz5Cmj3T15OE6Lxt6wXRQ&oe=64C5A1C2\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/362612448_699005205604366_4280290885472827984_n.jpg?stp=dst-jpg_p526x395&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=Pqli4RmTgyYAX_Lu7Nl&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfD856hZPcR7WAb7czA_YAZ28889WRY0MdP5ZgFV9-_v8Q&oe=64C60A52\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/360146719_699005238937696_3768431308898304664_n.jpg?stp=dst-jpg_p526x395&_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=Lo_d1HbHKTAAX_NkDkj&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfB4q8K8tJ2QEA5MU2Z7GmbzgffX8DyT7oeNtOqQClO7xw&oe=64C55DAC\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/360121604_699005252271028_5751256982783019845_n.jpg?stp=dst-jpg_p526x395&_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=LlFXWrmEwVAAX_0xEpe&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfCf24kyq4Qlhzt6S82st6JYqvcTD5e5Tvn-XyIdyPDNBw&oe=64C591CE\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/362227688_699005295604357_9099856387291898074_n.jpg?stp=dst-jpg_p526x395&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=y5_M2PBaJDcAX9n7uKl&_nc_oc=AQlMfj1AoVGuem-OEulZtu4oKgzXSq5_xMI-Fz5NLVCz7bkNpoN2pcN1b39TKp3-M2M&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfAmfejvb9AaWaDJBsPljkEF5e36ZH1bTyKy1EIbgQfxig&oe=64C56295\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0Jufsa3DYCakcSgTKFVxQPabndEAybYJN6LwXNmwM9EUQJEujK2QYJ7HpzuABaoK7l?__cft__[0]=AZUM2ApFIY264AjUuvGLXUQdXFe6kcrscf1e58cYB2jHE95itfnn9DMgmxdEZKXHLWsKbxL4NUCyDcXVv4tGvlHS8cJuqPlgezATSjTPN_c_VxRU3VONOjy1WF_3NOlLcVUh13WpllHo11D0bVXjrcA4S9UEA_RENibPWqv3IDUTy-SCNZzypqnpe5hu8RxKKqiX1f1mZhpTrgu1tFXTJrr9&__tn__=%2CO%2CP-R\"}, \"pfbid036pDFSd7gacTVwBrJq8DjsgU762dq9jTK7sgSFnHAAtUQwUo5x6xiAzwHNZjsyXygl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 1, \"reactions\": {\"likes\": 15, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 15, \"comments\": 1, \"content\": \"SESI LIBAT URUS KAJIAN SEPARUH PENGGAL RANCANGAN MALAYSIA KEDUA BELAS 2021 - 202522 Julai 2023YBhg. Dato' Ir. Rajendran a/l P. Anthony, Datuk Bandar Majlis Bandaraya Pulau Pinang bersama barisan Ahli Majlis iaitu Encik Abdul Latiff Bin Mohamad, Encik Mohd Suhairi Arumugam Bin Abdullah, Encik Hari Krishnan a/l Ramakrishnan, Encik Mohd Faruk Bin Abdul Rahman, Puan Rodziah Binti Abul Kassim, Cik Nurhafiza Huda Binti Idris dan Puan Goh Huey Ee hari ini telah menghadiri Sesi Libat Urus Kajian Separuh Penggal Rancangan Malaysia Kedua Belas (2021 - 2025) bertempat di Hotel Olive Tree, Bayan Baru. YAB Tuan Chow Kon Yeow, Ketua Menteri Pulau Pinang 'caretaker' dalam ucapan beliau memaklumkan bahawa Pulau Pinang telah berjaya mendapat kelulusan sebanyak 75 projek baharu di bawah Rancangan Malaysia Kedua Belas (RMK-12) membabitkan peruntukan berjumlah RM54.14 juta. Kelulusan 75 projek tersebut adalah sebahagian daripada 126 projek yang dimohon oleh Kerajaan Negeri Pulau Pinang di bawah peruntukan Rolling Plan Ketiga RMK-12 sebelum ini.Sesi Libat Urus Kajian Separuh Penggal Rancangan Malaysia Kedua Belas (2021 - 2025) menyaksikan kehadiran Menteri Ekonomi, YB Tuan Mohd. Rafizi Ramli serta Setiausaha Kerajaan Negeri, Dato\u2019 Mohd. Sayuthi Bakar; Ketua Setiausaha Kementerian Ekonomi, Datuk Nor Azmie Diron; barisan ahli Exco \u2018Caretaker\u2019 Kerajaan Negeri.\", \"posted_on\": \"2023-07-23T17:58:39.276732\", \"video\": [], \"image\": [\"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/360128269_698996282271925_8373859058183420792_n.jpg?stp=dst-jpg_p526x395&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=maZi0Xd_S7IAX_6MZTZ&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfCvaS-vTJcuKbCWiaeGKt-SbD8eXokjPb9cFj99_H9CoA&oe=64C545CA\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/362604134_698996592271894_4399314558248343384_n.jpg?stp=dst-jpg_p526x395&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=fGBpn2-S1hsAX8HT27z&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfDlKtNNaJO_hVYrq7Y_iG4mTQU1Z5IHqgef1FqIqlUFmQ&oe=64C4F7A7\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/360137883_698996635605223_4817414599037440352_n.jpg?stp=dst-jpg_p526x395&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=MuhENXDr2skAX-_0yQw&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfCAppNS_4Jgr6aGL_ZjoLDyDIulqIQ9tgPRr2Olt-0zaw&oe=64C6B3DC\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/362641464_698996662271887_2184762448622259664_n.jpg?stp=dst-jpg_p526x395&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qHILF1alJYUAX_5i72u&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfA43wpcis2pdTYZDkzbhsgszQi2LcxS72q0YUTJRzk6JQ&oe=64C59381\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/362684406_698996022271951_7061396978717357161_n.jpg?stp=dst-jpg_p526x395&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=cGgK8D8AAksAX_WNyyb&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfBHMwUL-8YcUZsgaoj_-q9d2f6V5kllPSQUdsLfuKywwQ&oe=64C67B5A\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid036pDFSd7gacTVwBrJq8DjsgU762dq9jTK7sgSFnHAAtUQwUo5x6xiAzwHNZjsyXygl?__cft__[0]=AZUn1VVr72xGCMsdoLjNCDXQ3t0THPcb76XpqLLKX9EFatIqRBhvtF5TwBiNldsRT31JY6cdTnTHvVAms_l4HM1B5dEodbKRts_KUi7kZZ6I5Qu0OzUvOChwjTLZT0bz8CVy8chBYdxjefmlPSKXVuslzGSd1R6HDetKanEqUFYm9PL-vWbuAbWZmC4UhG_JSpG2Bn0nD-zxzbycKmfmvT2a&__tn__=%2CO%2CP-R\"}, \"pfbid035UTJtKk9aeGHQg2kvdsjfLj3dmRDQzcRcyCJQmmQNUnsWsVAkbTJszHEYqetrVfCl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 16, \"loves\": 0, \"wow\": 0, \"cares\": 1, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 17, \"comments\": 0, \"content\": \"INFO POKOK TUMBANGLEBUHRAYA BAYAN LEPAS 22 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-22T17:58:39.527182\", \"video\": [], \"image\": [\"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/360115293_698773255627561_2859260089551737444_n.jpg?stp=dst-jpg_s600x600&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=n0QrRW9KBV4AX_gdUgW&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfAvu8YISZft5o3b5AHdANyFQ5ya22iE2ljJj__mLIJojA&oe=64C60EC2\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/360131132_698773285627558_3560834197011844721_n.jpg?stp=dst-jpg_s600x600&_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=_ytkJNYJUTYAX_okmkA&_nc_oc=AQniz271MWPtMt-03C_bvlnkDVyxEiPsqB9456kHdhwBvv8KjqvEBSPOAXgrb5pev_M&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfDMdR-KLtCurh8uT0SlqxCrZhZrSq2k6Q7WiD3BHfLtjQ&oe=64C5D981\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362636374_698773312294222_9125565501831116284_n.jpg?stp=dst-jpg_s600x600&_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=eezI9CnGS_UAX_x3oCL&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfAz9YowgCld59ndHDZrSbHYFgEoa6TMDnQIBtsRqe0RZQ&oe=64C59052\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid035UTJtKk9aeGHQg2kvdsjfLj3dmRDQzcRcyCJQmmQNUnsWsVAkbTJszHEYqetrVfCl?__cft__[0]=AZV8T43WZ2u0wX-1yfC8D4IzeuksVNXZ8x6oXggFWfU6s0qRyWikX0xBhh4wMTQLQVdWcGBJrRHiCM6LwJxIvLYej7rKLN98dhTEZhLCqwoAMSmyvjsZgooJ2Bm4LE9XUyPYzZNymqEGb3_cnc4jTbxShGWoTL9-QRqRhpXDExKX5eCTaRJ2WefOG3CfyOPI1Ahy0J2iAAKv3V--oBMpQafp&__tn__=%2CO%2CP-R\"}, \"pfbid02ZWhjhUQHNBC2KwwQoUuXMBJXF6YsieGcKBUge9ntg3m4mcxdHkPh36oxYcnpeLvKl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 39, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 39, \"comments\": 2, \"content\": \"INFO POKOK TUMBANGMEDAN MAHSURI 122 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-22T17:58:45.040701\", \"video\": [], \"image\": [\"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/360116935_698756602295893_7704228780308948517_n.jpg?stp=dst-jpg_p600x600&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=QQvieDXp_4oAX-Qi2kr&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfAsVRoYyL2TJq2fyXiG-el34Zs-14DUdYkpx84-NKiT3A&oe=64C52B50\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/360126189_698756652295888_5637945379762085324_n.jpg?stp=dst-jpg_p600x600&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=-lAJc-7jvXoAX9P-kdH&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfBWtwhDj-9sc5jVNyCMpBcAH6PdKlXAL9lf6au1CgssMw&oe=64C5B8A9\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/360117794_698756665629220_4139343876458038468_n.jpg?stp=dst-jpg_p600x600&_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=JUlsTOgCGZMAX8PJVzN&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfA47sDCkCMHlaIEHT58iC3bBAlmogIFhtEZAeK2-rawzA&oe=64C69753\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02ZWhjhUQHNBC2KwwQoUuXMBJXF6YsieGcKBUge9ntg3m4mcxdHkPh36oxYcnpeLvKl?__cft__[0]=AZWAGH7jTWGloXaAE5qu7n-KQOpfSxvOSWWHyj4NC60DnsNzomXuxtw5_UiRr8K2Z41kgfnS48NQo-o_-7k-TtuxofZEK2_mMMaz-fbkdegfANz2RYgNov6UoaqzljWyf2CQZSY40xECHMDjUU_b-XXsaDYWpmrP0VWsNHz0GLwAmR0cyPjApsm6Lo0Sc521hFLd9XWbjFBmSYj_13uL3j8A&__tn__=%2CO%2CP-R\"}, \"pfbid02a2Qdpbgyt2dHvzQ6CKUTqFRhmBpoNNsacjzumP76yJCHHXqkmFcXedLB1MunqdKWl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 39, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 39, \"comments\": 2, \"content\": \"INFO POKOK TUMBANGHADAPAN PASAR BAYAN BARU 22 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-22T17:58:45.321013\", \"video\": [], \"image\": [\"https://scontent.fsgn2-8.fna.fbcdn.net/v/t39.30808-6/362628496_698755275629359_6301137382907133690_n.jpg?stp=dst-jpg_s600x600&_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=DeZnVC_H5WcAX-XhfHd&_nc_ht=scontent.fsgn2-8.fna&oh=00_AfA9z8ekklq4rqd8xQKdKjyWGEaIJuw4eoG5AaILBGZ-sw&oe=64C6CEC8\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/360119381_698755305629356_7136193953232807712_n.jpg?stp=dst-jpg_s600x600&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=f0yQhGjPWpwAX9tIDJD&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfB--4_vaN2BCVwWQTCjXjWEYUMDTBgrlM5tjUJFTlbg8Q&oe=64C52446\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/361616227_698755332296020_8627929541952470794_n.jpg?stp=dst-jpg_s600x600&_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=3qMLioMTPy8AX-B77m4&_nc_oc=AQl_wPVjpi8TT3et8AX2RVDfeQRpTPReRSQvdj53y5vj_shndoNEY8nGSJuI4GmXQPc&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfAfGIS6Y0ZM0sakCRkpol8JSKcBFj4155k0AGTzbFhnSg&oe=64C5F9E2\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02a2Qdpbgyt2dHvzQ6CKUTqFRhmBpoNNsacjzumP76yJCHHXqkmFcXedLB1MunqdKWl?__cft__[0]=AZVx-RL2vKpMWGrUfBVHQm3iN9DJmO8Hb8iov60afoDSpRITKQySYS1OnII18Rz9wlGKiHRr0mA2XaS7vlALz7LlvLE2Ae_8qV3UV9_m7up1ntIEVJ1yVJqVreojHyKLnOGqFxMoUQQmO7T3UeRxvOKLdKbeiEAlgI2NJZfjYxjz2OUcpNKoJerS65wbyR1JxNPc0IDCLSiZtyNblm-8s7gY&__tn__=%2CO%2CP-R\"}, \"pfbid09XodCkdtvPHpTJmi59P8qayP4KKiFkzzr8WnNwewotGhqyNWijDVSieHM7SuRhdnl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 2, \"reactions\": {\"likes\": 25, \"loves\": 0, \"wow\": 3, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 28, \"comments\": 2, \"content\": \"INFO POKOK TUMBANGHADAPAN SILVER JUBILEE HOME22 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-22T17:58:45.707458\", \"video\": [], \"image\": [\"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362657990_698724618965758_7595807359021937228_n.jpg?stp=dst-jpg_s600x600&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=pgmCyVGejMcAX9G0Q6j&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfCc_PG3b4FAjZCj7Vhblpj1DZmRlNsF1PllrrhD2i28XA&oe=64C6E716\", \"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/362629652_698724735632413_8556638981431436519_n.jpg?stp=dst-jpg_s600x600&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=INp9kj0dzuEAX_-7-IZ&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfAn8yAKjJYbYiSTdgE6PetCEkB8ATNpEjZF4TNACVCdhA&oe=64C5DA99\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362209961_698724668965753_7973651823909167172_n.jpg?stp=dst-jpg_s600x600&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=PP61JrLatGEAX_a-VlI&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfDKIoVhI-NtUpp7OF6J8BPN_yAN1j1nBU0vrYprX6sg-A&oe=64C51F20\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid09XodCkdtvPHpTJmi59P8qayP4KKiFkzzr8WnNwewotGhqyNWijDVSieHM7SuRhdnl?__cft__[0]=AZVCzJVtlGAbG17-uKn7MYh86bZseMEBfWsQpnPTMW8d2uAEjd0rCKEcsYCi4rZW_mUw3K7zk_uWE7BZ7fyJx-fkV7hnCoorIAjTAHGgxcUL8At5z6nM4s0oNINHF1JIscYFZ4ptC3nZAInra4044QnCI2YWfgIaJGkwLx89Y7oYPLsTfWTlN-nxvlyPG5_xiFk06ErTOUaSlXanNr7Rqm2O&__tn__=%2CO%2CP-R\"}, \"pfbid021bhdyh3EGcKRBt9CanHFEjaSKFZzBUDpU6SK6S9koi1bkCzCsn6kA3brBFWULbSbl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 16, \"loves\": 0, \"wow\": 2, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 18, \"comments\": 0, \"content\": \"INFO POKOK TUMBANGJALAN BUKIT KECIL 222 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-22T17:58:51.219047\", \"video\": [], \"image\": [\"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/362627289_698715595633327_5515922438878597914_n.jpg?stp=dst-jpg_s600x600&_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=0IJrwXZpcrYAX84Df0K&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfA1A83lj21K4gIg6FI7w-Aw-GtYacrZJdIM85gV9t8hKA&oe=64C636AE\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/361926849_698715638966656_8208158456639695975_n.jpg?stp=dst-jpg_s600x600&_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=SwD4xUEWiR4AX__anTG&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfCfXwwnZAw94RVYoV-43xLYtbvFz7CKI5AAvbJ5hKRRMA&oe=64C63928\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/362641614_698715665633320_3616259970553896466_n.jpg?stp=dst-jpg_s600x600&_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=wOH6n9AiqiwAX9As_Ma&_nc_oc=AQk928cX-sKtkJyg6XQ6WueRU6yHFEGN-stcBSG-54brSve7eb3irOSSXjRZmJEgA0o&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfCEjc3ZkDL1AhH2xxm-0coGZBACYlfuT7tOnT2g5-Dmug&oe=64C63203\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid021bhdyh3EGcKRBt9CanHFEjaSKFZzBUDpU6SK6S9koi1bkCzCsn6kA3brBFWULbSbl?__cft__[0]=AZW66EEb_OrtGoyvD57sDc7Q8SRqVkz7OJcsV8hNvrDfE1uC50bCH8KXDam4be4VTHpcwWdy0u0wG-0weYSInPU4ezirT8YlNeMPu05cX7JniY4jEF-bMX13NVJg2xVKHevseLAjmvQIsRFV-VUi9XAJHw3vds-E11h7t3Uyg6tgYfccShYJSpwKy_bfy1_I0gR2Csqss1Qr0RmPecRpdDtU&__tn__=%2CO%2CP-R\"}, \"pfbid02679eyeEawuFhDpb84KWDVTgjhKCELcpAwmtQzDAhccznY6zvu8e2mHhVamiQj166l\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 17, \"loves\": 0, \"wow\": 2, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 19, \"comments\": 1, \"content\": \"INFO POKOK TUMBANGJALAN AZIZ IBRAHIM 22 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-22T17:58:51.395595\", \"video\": [], \"image\": [\"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/362630115_698712692300284_3222880040199970031_n.jpg?stp=dst-jpg_s600x600&_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=B38KweIqdjcAX-vG1YQ&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfDHgc_UI9a-9vGMwfq0XLLouy4NSV3i_6ux7aFgXXTSCA&oe=64C5B0FE\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362640385_698712762300277_320020135111281805_n.jpg?stp=dst-jpg_s600x600&_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=x0ZnFt3fxwcAX-8zqco&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfC3PxlXXbn0-tBuhMUfcpvRmxSEvRgIJ7xshL30huDlyA&oe=64C4F1C2\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/361252399_698712812300272_1640835525290941220_n.jpg?stp=dst-jpg_s600x600&_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=_Mfc3vgK6SwAX-tqB36&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfDYJCA5umBl_3s5gXf79pO__NjFbr97Rx47zEOoJd8ZiA&oe=64C66DC5\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02679eyeEawuFhDpb84KWDVTgjhKCELcpAwmtQzDAhccznY6zvu8e2mHhVamiQj166l?__cft__[0]=AZUxZf8U7dRYrLNr2j99yH7qDneC8AfmbDKU7sujLn_0XNLqowDJw10LyHn121HyJjJCxH5ovwdVBk8gm0KqtGR24ZLSINZ4mUllqEJxGDJzN_04JTyeog3UUI9EXodCuA9B7PgReVLKLZi_aKOr5Lg8_RyWcmsMuFBrM8h4Z-qQa2MwDtHkzRhaorOgjyau-NE1DZCugWfcheS_OCVf6ZNc&__tn__=%2CO%2CP-R\"}, \"pfbid0kYmTL58u8qEgX3rR8bpVub93D1XBG3SsFaF6Qks4mHtBqURkivEzoUmoD1RWRMtl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 1, \"reactions\": {\"likes\": 27, \"loves\": 0, \"wow\": 2, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 29, \"comments\": 1, \"content\": \"INFO POKOK TUMBANGJALAN SULTAN AZLAN SHAH 22 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-22T17:58:51.613152\", \"video\": [], \"image\": [\"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/362248422_698710018967218_835745851868839934_n.jpg?stp=dst-jpg_s600x600&_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qqytprtCzYEAX-R9Zt2&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfD_eNl3YKZuQtAnG5KRP3QbMiFKO9zRJO7pS4rs2tDPdQ&oe=64C550DD\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/362632548_698710042300549_2121703060050757830_n.jpg?stp=dst-jpg_p600x600&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=yw9K-T0bKeUAX99rq6w&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfA2JL5Ew6UiO4RL12_ABQiKYsUvFH1dAMBVQ8jaX--VlA&oe=64C56D55\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0kYmTL58u8qEgX3rR8bpVub93D1XBG3SsFaF6Qks4mHtBqURkivEzoUmoD1RWRMtl?__cft__[0]=AZUsA8IDZxRZ15QOib11rFLLba-4Cj1djjALq2kHIXGx64PlAS7ojyH3k4yZPGTqfilEtdA1-mxpEx7ckX3XOlwpSTDkDpDfLAL-b05hW7U_OvFYU5dq-giphBO6HHHSYs_X1XMPmEnv3K5diI3KOJF1JycwlLTCrr2RNRjNzzgex_2wV67ZgRkrDhoN19gV8Jn_l-K0fAqQgFN40fG0ebeH&__tn__=%2CO%2CP-R\"}, \"pfbid0xvJ6FJ3wCVh3kFtBdANFcPBx4msxFjrYVmcRDX3QjF6j277qu7SmxygotyenjsLkl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 6, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 6, \"comments\": 4, \"content\": \"Semarakkan Bulan KebangsaanKibarkan Jalur Gemilang\", \"posted_on\": \"2023-07-22T17:58:51.743948\", \"video\": [\"blob:https://www.facebook.com/8cd65668-e7d0-4fab-b06f-02543a3e33f5\"], \"image\": [\"https://scontent.fsgn2-5.fna.fbcdn.net/v/t15.5256-10/362232314_183433588055105_7691584752091055827_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=ad6a45&_nc_ohc=ZaX5zlHdHAwAX_huoVx&_nc_oc=AQltgMfg4SWViQyPlL_bjbpWbc2lgkrIIfnCREnXAjq10HNSCaC3N-STg6GYVgbSvqY&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfAOZ8S8ymyGyJnlr186MWFoMSzEFQ7dlz5SJ3QqhLx4cw&oe=64C5373B\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0xvJ6FJ3wCVh3kFtBdANFcPBx4msxFjrYVmcRDX3QjF6j277qu7SmxygotyenjsLkl?__cft__[0]=AZXncyj6gtgTOURVam2ZSfnBWSI5_y4QNAoDEVVNW5E6iNAtYwyMHiM8Z79vyXAr9h0tjBmp5g5IoKrd6RXvERNhmPj8mGs7J62YDLzGRPm5X6io9n7xbzJ_hN4XAj8amq5dhqeeuvSqQkdt-ZU2Kku63tCcQ0PiXd_7OM7et46r9d4vEFX4LL0605x9L3Y7PE7cEqE--TiBHYYZoCQLuY80&__tn__=%2CO%2CP-R\"}, \"pfbid0ShoQP5pVepnbygK1PvxaEdLEerzBzf9zxdRrwPXx3gatT2HMS3SwL9YxSdSWQJhUl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 4, \"reactions\": {\"likes\": 66, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 66, \"comments\": 6, \"content\": \"INFO POKOK TUMBANGLEBUH NIPAH22 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-22T17:58:51.915895\", \"video\": [], \"image\": [\"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362653754_698673485637538_2356267571398521308_n.jpg?stp=dst-jpg_s600x600&_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=YBNJ6ZoiyeIAX_awZVU&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfAvUtQr5WYw-o5og2VY88eMJjLg54vVHLJG7SDhwArECA&oe=64C59040\", \"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/362670011_698673518970868_8008559306642148648_n.jpg?stp=dst-jpg_s600x600&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=ajIWQN_wvyAAX9OaREP&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfDbL7Hp0T18wA40GibX7PJg-0CY6sYxBmVk0E1B5mvvVQ&oe=64C55FDE\", \"https://scontent.fsgn2-8.fna.fbcdn.net/v/t39.30808-6/362660656_698673545637532_6487270052334535329_n.jpg?stp=dst-jpg_s600x600&_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=DRB3cPwAqHoAX_Gztll&_nc_ht=scontent.fsgn2-8.fna&oh=00_AfChFzLdLS4Okbr6TgxLEtzgyrgyzTKZK9vi8CE9_GJMjw&oe=64C53FD8\", \"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/362610223_698673588970861_5957488916058816984_n.jpg?stp=dst-jpg_s600x600&_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=XgLFCvtz-pQAX9wT0ev&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfDbLE8F6kI3c_UlqR8obppsi6wvIzkGOvjqFMZc_hIuBQ&oe=64C51D15\", \"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/362289016_698673628970857_2252978794896793210_n.jpg?stp=dst-jpg_s600x600&_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qyLOC75gxSUAX-3JvM4&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfDDpCdHO1OjcleXuLiH367Tggincg9pzlygzNCis1fNdA&oe=64C5CCD9\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0ShoQP5pVepnbygK1PvxaEdLEerzBzf9zxdRrwPXx3gatT2HMS3SwL9YxSdSWQJhUl?__cft__[0]=AZUT7pjlceD-2p7gHhx1WMdCx2xmUp6Abvp3K-I1NE5p6Ia2h09D4fHYW_7wYDRSDHuhZi4bf4_wPOfBDUcEhXTaDFC-nyvC92MLyMaVWTg0fbF8Q7jsGuynVoT8yxsm1Y0bVeXp7KWBAXlBz09TronniCCArO1TA4yDpvccRZUBKVOvI7EAKepGFoV7v6qcsDKD5ZtG1wWjKd3JGJoRuXCh&__tn__=%2CO%2CP-R\"}, \"pfbid02qEcDYz5X6FFRVJqyvLvoWdKbtaK9RHkotPdAvUn21qf4XBquYssBraTCTcr7xsxkl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 2, \"reactions\": {\"likes\": 43, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 43, \"comments\": 3, \"content\": \"MAJLIS PELANCARAN BULAN KEBANGSAAN DAN KEMPEN KIBAR JALUR GEMILANG PERINGKAT NEGERI PULAU PINANG TAHUN 202322 Julai 2023YBhg. Dato' Ir. Rajendran a/l P. Anthony, Datuk Bandar Majlis Bandaraya Pulau Pinang hari ini berbesar hati menerima bendera Jalur Gemilang bagi pihak pentadbiran ini daripada YAB Tuan Chow Kon Yeow, Ketua Menteri Pulau Pinang sempena Majlis Pelancaran Bulan Kebangsaan dan Kempen Jalur Gemilang Peringkat Negeri Pulau Pinang Tahun 2023 bertempat di Perkarangan Dewan Bandaraya, Padang Kota Lama, Pulau Pinang. Penyerahan bendera Jalur Gemilang pada majlis ini meliputi 21 Jabatan Negeri, 19 Jabatan Persekutuan, 11 Agensi Negeri dan 10 Agensi Persekutuan sebagai simbolik bermulanya kempen Bulan Kebangsaan pada tahun ini.YAB Ketua Menteri Pulau Pinang dalam ucapan beliau menyeru kepada seluruh penduduk negeri ini untuk bersama-sama menzahirkan rasa cinta kepada negara sempena kempen Bulan Kebangsaan pada tahun ini sejajar dengan tema Malaysia Madani: Tekad Perpaduan Penuhi Harapan.Majlis yang disambut meriah oleh semua jabatan-jabatan, agensi-agensi kerajaan dan pertubuhan bukan kerajaaan negeri Pulau Pinang turut dihadiri Dato\u2019 Law Choo Kiang, Yang Dipertua Dewan Undangan Negeri ; Prof. Dr. P. Ramasamy, Timbalan Ketua Menteri II ; Dato\u2019 Mohd. Sayuthi Bakar, Setiausaha Kerajaan Negeri; barisan ahli Exco Kerajaan Negeri dan ramai lagi. Majlis Bandaraya Pulau Pinang turut diwakili YBrs. Sr. Cheong Chee Hong, Setiausaha Bandaraya serta Barisan Ahli Majlis-Ahli Majlis, ketua-ketua jabatan dan para pegawai. Kemuncak pada acara ini, YAB Ketua Menteri Pulau Pinang diiringi dif-dif kehormat menempurnakan pelepasan Konvoi Kembara Merdeka Jalur Gemilang 2023 yang dibarisi oleh 40 buah kenderaan terdiri daripada agensi awam dan swasta sebagai simbolik Pelancaran Bulan Kebangsaan dan Kempen Jalur Gemilang Peringkat Negeri Pulau Pinang Tahun 2023.Marilah kita bersama-sama semarakkan Bulan Kebangsaan dengan mengibarkan Jalur Gemilang.\", \"posted_on\": \"2023-07-21T17:58:52.436773\", \"video\": [], \"image\": [\"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/362603383_698166379021582_8496098007101979771_n.jpg?stp=dst-jpg_p526x395&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=NCVVUjzhcxQAX_xOBM9&_nc_oc=AQnTYvozVo7GshVfE25xifrEkn_sz2hQRNN77Y3UGHUaIg1r6cZouFoZmKK_tgywBjk&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfC9khLHQ8jK_wt_gQcTg1n0tjagKfhrQjTqcsWXgrzzPA&oe=64C545A9\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/362611613_698167272354826_5450829947580967536_n.jpg?stp=dst-jpg_p526x395&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=SUzsmaG5u5EAX9kZcWs&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfAx1O0-CIENkwf_B6WA1wJWDoLypl3oW94VtyaIhiQQNQ&oe=64C606C5\", \"https://scontent.fsgn2-8.fna.fbcdn.net/v/t39.30808-6/362272456_698167319021488_7302875763157411175_n.jpg?stp=dst-jpg_p526x395&_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=aFnSVmTLSgIAX_BkdJj&_nc_ht=scontent.fsgn2-8.fna&oh=00_AfCVv20eOz7YATLVJAt4MWMHaHL9BKcgZs5xi_LyixeC-g&oe=64C6B119\", \"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/362274854_698167359021484_9125091432323716108_n.jpg?stp=dst-jpg_p526x395&_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=Qozh7QkFlK0AX-7Hcsc&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfD9Ki6YM-Ezzm-82G3r6Qp4pQ1PrO3ERWmM4AWtxDm9aA&oe=64C65A6B\", \"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/362224787_698167402354813_4191587930795062071_n.jpg?stp=dst-jpg_s600x600&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=a2XaeSUJDUMAX-4X2Gv&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfB4AI-Jpke4wM3Mi6vaI1Ghy9GUbufWeU4a4cVScuQw5A&oe=64C6DE5A\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02qEcDYz5X6FFRVJqyvLvoWdKbtaK9RHkotPdAvUn21qf4XBquYssBraTCTcr7xsxkl?__cft__[0]=AZXu-yoTJ0gbGW8VXld2fzqYkWULbyFASWN5bjzpco7XOB6j83D8aw3ycP2RRWHNP_8m4uhBo_pzvjfxvDsfKuZOtn6FlIYWeIOv_ohao1oVSHdjvXLdNuEyhOQnpLISRJ6xffQaNW1yxTfKaGk0-xiykJFWJdRdM8lZU4v0aLVc4Gynw9OdNZCY5uJ2EH-IEc7NQb8HbqNdnHLVUy1-zZvE&__tn__=%2CO%2CP-R\"}, \"pfbid02QCzDK89BCkPinmYrpkrBHhmWyGMhZcmoLcis6QC6NAjVNgzWVXhEm8ep28z81yRTl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 5, \"loves\": 1, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 6, \"comments\": 0, \"content\": \"Majlis Pelancaran Bulan Kebangsaan Dan Kibar Jalur Gemilang Peringkat Negeri Pulau Pinang Tahun 2023 l Padang Kota Lama | 21 Julai 2023\", \"posted_on\": \"2023-07-21T17:58:58.161261\", \"video\": [\"blob:https://www.facebook.com/4a8cd8bc-ece8-49d9-a221-d7967dc21561\"], \"image\": [], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02QCzDK89BCkPinmYrpkrBHhmWyGMhZcmoLcis6QC6NAjVNgzWVXhEm8ep28z81yRTl?__cft__[0]=AZWxTuu_ZJu2kWJo8bYEHLV_YlaqDMiK1dMBcU2X9QvX0DCF_4lW1iUFEIhKSa1partslvUIfNFn5WPHa7tbe2xMxTlXS3hIopUJojsIh6qaftUHO8tvGjNdby_KiazpWRMZuBwrPwvKd9VT7lci8wJ2HZ-8plHMpdEtoUm1CYWeIMHRK8QoyWr3emQR9eEoINlsJmbQ67rOjzCkMmBDzi9MzjJbq1ZiMWudOjSEQ6Rjp9U5gW0rNJxcpzGYLOmvpIc&__tn__=%2CO%2CP-R\"}, \"pfbid0BpvzqofAc357z3YquBpQxMLsRSqjizWt8oBf5ym9n5jQYoqzYumsphVo1Rqt6qoil\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 3, \"reactions\": {\"likes\": 34, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 34, \"comments\": 2, \"content\": \"PARA PENTERNAK LEMBU DI BAHAGIAN PULAU, PULAU PINANG DISARAN MEMOHON SEGERA LESEN PENTERNAKAN20 Julai 2023YBhg. Dato' Ir. Rajendran a/l P. Anthony, Datuk Bandar Majlis Bandaraya Pulau Pinang hari ini menerusi sidang media amat mengalu-alukan para penternak lembu di bahagian pulau, Pulau Pinang untuk segera memohon lesen daripada Majlis. Majlis Bandaraya Pulau Pinang dalam usaha mengenalpasti lokasi yang bersesuaian untuk aktiviti penternakan lembu melihat kepada tindakan melesenkan penternakan lembu tersebut adalah merupakan kaedah terbaik agar penyediaan dan pembinaan kandang yang bersih, selamat dan tidak menimbulkan kacau ganggu setempat. Seramai 15 daripada lebih 40 orang penternak kini mengambil langkah pertimbangan dan sedang berusaha untuk memenuhi syarat serta keperluan permohonan lesen yang ditetapkan oleh Majlis Bandaraya Pulau Pinang. Encik A. Halim Yusof dari Balik Pulau merupakan salah seorang dari 3 orang penternak lembu yang telah memohon lesen daripada Majlis Bandaya Pulau Pinang dan beliau telah berjaya menerima lesen penternakan lembu pada 18 Julai 2023. Majlis Bandaraya Pulau Pinang bersama pihak Jabatan Veterinar Pulau Pinang akan mengambil langkah lebih proaktif dalam usaha pemberian lesen penternakan lembu. Ini bertujuan untuk memastikan isu keselamatan awam seperti ternakan lembu berkeliaran dapat dibendung dan ditangani secara berperingkat disamping memperkasakan punca rezeki para penternak. Hadir pada sidang media tengahari tadi adalah barisan Ahli Majlis Encik Ts. Kaliyappan a/l P. Renganathan, Encik Nicholas Theng Jie Wey, Encik Wong Yuee Harng, Encik Hari Krishnan a/l Ramakrishnan dan Encik Quah Boon Lim serta ketua-ketua jabatan dan para pegawai Majlis Bandaraya Pulau Pinang.\", \"posted_on\": \"2023-07-20T17:58:58.329423\", \"video\": [], \"image\": [\"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/360098430_697651949073025_640003213501297314_n.jpg?stp=dst-jpg_p526x395&_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=VgQeyqAUUxYAX_aqTpf&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfAd7A2k4phFzA5hJhoUnXfA1aFPECv_1STizvwW6NTgzg&oe=64C577FF\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/360095619_697652002406353_8227673600874327725_n.jpg?stp=dst-jpg_p526x395&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=X8ZJ6X9w8boAX9eNNob&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfAQXTRGVljCbOnkeu-6sOyXJEFVZ-M76iEGsH1mmbR-rQ&oe=64C52920\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/362260335_697652022406351_8997611359658994169_n.jpg?stp=dst-jpg_p526x395&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=cf77ICE6LJ8AX-lcSen&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfA5uAejtm-1pWaCaR_6vzfHubO2_xLDXSrg_qp1wZI5dg&oe=64C57571\", \"https://scontent.fsgn2-8.fna.fbcdn.net/v/t39.30808-6/360094668_697652052406348_3300277076202623102_n.jpg?stp=dst-jpg_p526x395&_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=Ha3q15B4uegAX_PzJr2&_nc_ht=scontent.fsgn2-8.fna&oh=00_AfCdr7glnSg-Wn00cBHoMGM7yxdpJx-7ccrKva7MIPuGdw&oe=64C4F4A3\", \"https://scontent.fsgn2-8.fna.fbcdn.net/v/t39.30808-6/362001260_697652069073013_1074279373947440913_n.jpg?stp=dst-jpg_p526x395&_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=xDUROLXKo60AX_DwvOG&_nc_ht=scontent.fsgn2-8.fna&oh=00_AfC65cfuAiwONLiuY-n-U11zo5AlJ6iXUnBaCKCeSvHrMg&oe=64C50672\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0BpvzqofAc357z3YquBpQxMLsRSqjizWt8oBf5ym9n5jQYoqzYumsphVo1Rqt6qoil?__cft__[0]=AZUWGVkELi5MDyZNBXDiXxa7C7Mzx6BDa_EgYq78q-Db15myC4eTyuPux0JXBumgjGH_kgTfzyLbjCMqfMxzaM_LC2fq6nW0QWdU_OFuz7KYapnNEGcy91PfKwioDINs51ZDu6mibcqFlHtfdr9_s_COocf3rG0FL_u-Wv_Yhz8baWSGV6eLyqg9XmkBPtqxI7sjfxPV_RmrvEfy0buvYjt6&__tn__=%2CO%2CP-R\"}, \"pfbid02Ex7MSos7LVxaGD3K9vMghSEFsUJxNFguJqDo8KPhbqB52yXPXTq1xaiqZ39uCZKkl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 8, \"reactions\": {\"likes\": 33, \"loves\": 0, \"wow\": 0, \"cares\": 2, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 35, \"comments\": 1, \"content\": \"DATUK BANDAR MBPP TERIMA KUNJUNGAN HORMAT DELEGASI YALA CITY MUNICIPALITY, THAILAND20 Julai 2023YBhg. Dato' Ir. Rajendran a/l P. Anthony, Datuk Bandar Majlis Bandaraya Pulau Pinang amat berbesar hati dan mengalu-alukan kunjungan hormat Mr. Pingsak Yingchoncharoen, Mayor of Yala City Municipality, Thailand bersama Konsul Jeneral, Royal Thai Consulate di Pulau Pinang, Mr. Raschada Jiwalai, dan delegasi barisan pengurusan tertinggi Yala City Municipality, Thailand.Pertemuan yang amat bermakna ini mengeratkan lagi hubungan dan kerjasama dua hala dalam aspek tadbir urus cekap pihak berkuasa tempatan, ekonomi, warisan kebudayaan dan sebagainya. Turut hadir bersama pada hari ini Ahli Majlis MBPP, Encik Dylan Lee.Kunjungan delegasi Yala City Municipality, Thailand juga dibawa meninjau pengoperasian pusat Intelligent Operations Centre (IOC) MBPP, Galeri Dewan Bandaran MBPP dan Tembok Padang Kota Lama Esplanade (Seawall).\", \"posted_on\": \"2023-07-20T17:58:58.542955\", \"video\": [], \"image\": [\"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/360094733_697634592408094_4432624279774512831_n.jpg?stp=dst-jpg_p526x395&_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=hIdJxRkwzZ4AX8j0g_x&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfAwgIcDkl16w2cnP76g4PxcQ9ibF87CnRMzEtJ74nBNGw&oe=64C6B815\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/361882709_697634755741411_7775585732076341593_n.jpg?stp=dst-jpg_p526x395&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=xeM2P4pKcakAX9FiX3Y&_nc_oc=AQmhbyMgSosigjdOUNNh0Mx4lxf6WYMt6b8-JdPo-O38mqylOxZy43QMTzlf6Zf_Ohg&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfCTB-4bTRoC7i_ksDIMhnUNyGO3pvyDrIwUgDyjzdRy6Q&oe=64C52A34\", \"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/360097540_697634772408076_301497414380405554_n.jpg?stp=dst-jpg_p526x395&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=ramH49tmSsgAX9lxmG0&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfAZN_vY1p7gKjuKNTTr9qYMbwKXdTTv1VZ51RxfWSFBCw&oe=64C51442\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/360094206_697634789074741_3502066041685493020_n.jpg?stp=dst-jpg_p526x395&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=A07Maa07GZYAX9LRKDX&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfAnwj8Dkald77LnL7x8jUMzw1pbHjQtonr0tCTN0A5QTw&oe=64C69D9E\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/360098900_697634805741406_4430730880116208769_n.jpg?stp=dst-jpg_p526x395&_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=zj3JnaYxIeoAX8Pk_ZK&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfB42bHx1HysRThNd-JjJipr-F9-dNF7ZOdFPFWkRjFZ_g&oe=64C64226\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02Ex7MSos7LVxaGD3K9vMghSEFsUJxNFguJqDo8KPhbqB52yXPXTq1xaiqZ39uCZKkl?__cft__[0]=AZWuCj7pyjJnenkdlnfWgoGJHe_vSVQrfSRHEgkcg3SoJQesDmHQdyohBT6UmVpfqDLrFAWj5l_XFGI6N-6xCGRKprfn1L9wwKs7tgnlKVbBdWON5fPNmWoZfzk0-iiV6coaR0fcJIclj-5YzyKPfGq03lu97n--dTXvlbE62Kei6WgJCV7R8AT3Rv9RpLscIUS1nqIbySm_OOxYwg8c5X-w&__tn__=%2CO%2CP-R\"}, \"pfbid032iTkWehRMvLJn3sQmZTZj7UCagVzRf18hKSaZAQp9fLPz3VSWi6uGiLqjMdW3H84l\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 29, \"loves\": 2, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 31, \"comments\": 1, \"content\": \"IPSI TINGKAT KESELESAAN SURAU BANDARAYA PERKASA PENGIMARAHAN IBADAT 20 Julai 2023Para pengunjung Padang Kota Lama yang beragama Islam dipelawa untuk menunaikan ibadat sembahyang di Surau Bandaraya Lebuh Duke, Padang Kota Lama. Ianya terletak di sebelah bangunan Pusat Bayaran Setempat MBPP di Padang Kota Lama. Surau berkeluasan kira-kira 160 meter persegi ini dibina di atas tapak letak kereta dan berkeupayaan menempatkan 70 jemaah dalam satu-satu masa serta mempunyai kemudahan tandas untuk Orang Kelainan Upaya (OKU).Justeru itu, YBhg. Dato\\\" Haji Kamaruddin Bin Abdullah, Ahli Majlis MBPP merangkap Pengasas dan Presiden Pertubuhan Penyebaran Islam Antarabangsa (Islamic Propagation Society International - IPSI) hari ini berbesar hati menyumbang dana sebanyak RM2,700 bagi tujuan penambahbaikkan kelengkapan Surau Bandaraya di Lebuh Duke, Padang Kota Lama. Surau Bandaraya yang diilhamkan oleh YBhg. Tuan Haji Mohamed Yusoff Bin Mohamed Noor, Mantan Ahli Majlis MBPP telah siap dibina pada 14 Oktober 2013 dan secara rasminya dibuka untuk kegunaan orang awam pada 18 Februari 2014.Hadir menerima sumbangan ini adalah YBrs. Encik Azman Bin Sirun, Pengarah Khidmat Pengurusan MBPP.#suraubandaraya#mbpp#lebuhduke\", \"posted_on\": \"2023-07-20T17:58:59.023741\", \"video\": [], \"image\": [\"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/360152147_697628522408701_2667165696187226115_n.jpg?stp=dst-jpg_s600x600&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=x3kSdL5sbZkAX8L8mBt&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfALJoFptLOV9dXsVXJLZx2im2YU2HlhtRTv7LfjPchcJQ&oe=64C649A3\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/361638361_697628595742027_7157312587354720691_n.jpg?stp=dst-jpg_s600x600&_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=lzQrJJJC3lEAX9ezLUl&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfDX4fOJq8gZ8FcHedYB1mi7Fr7UmNT63fCNWIUYmck14Q&oe=64C64F4F\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/361893991_697628615742025_3207588188751161892_n.jpg?stp=dst-jpg_s600x600&_nc_cat=106&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=Xf70Fvg7eUkAX_qoSxe&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfAPcNVstrbR5XK0tfXSB4aGBWbMQ2lSsCOn7A5KfmWf6Q&oe=64C6B94F\", \"https://scontent.fsgn2-8.fna.fbcdn.net/v/t39.30808-6/361646143_697628629075357_8407202877837637241_n.jpg?stp=dst-jpg_s600x600&_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=QZliDEhhGnQAX-hP5jX&_nc_ht=scontent.fsgn2-8.fna&oh=00_AfDieeBjh2m-qWDxvb975XLvW9xjQR6IAf4sCnVFfo1ucA&oe=64C580A4\", \"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/361569887_697628639075356_1331101627407144688_n.jpg?stp=dst-jpg_s600x600&_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=jpfW0c1gKYAAX9eHnOb&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfB-TolkmcXYpYHLLpG2iG-f431_h_I5lD0xWTiM8a76hA&oe=64C5029C\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\", \"https://scontent.fsgn2-8.fna.fbcdn.net/v/t39.1997-6/105258811_1000519497070421_1877687988442182543_n.png?stp=cp0_dst-png_s110x80&_nc_cat=1&ccb=1-7&_nc_sid=ac3552&_nc_ohc=U8qN7u1Knh8AX-zcaE_&_nc_ht=scontent.fsgn2-8.fna&oh=00_AfATI7ehDNL-uN09IS5uKibhs1FgGxyVAxDJR27yxDtxgg&oe=64C5406B\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid032iTkWehRMvLJn3sQmZTZj7UCagVzRf18hKSaZAQp9fLPz3VSWi6uGiLqjMdW3H84l?__cft__[0]=AZVUVy9f-asibu7roWf8xrSWE4maNKfJFw_YJbbKtr3LCKI11ssDi63ilq34WXVUsDHwgUvIqOPojTQCraP6ABvLrqPaEluMG-4ezQDVZgbG1NpyGlvKm7kB_06xzJGB7nBHeafNOFPM-oqZsDt9NcO2lLS5uZ6m4o2egDX4GPc1uy-XCPPF_07QAk6iAQWrMU07dk6ET6AtthryQ1b29pSG&__tn__=%2CO%2CP-R\"}, \"pfbid02G7bt24Hq4vLiJ8e4MtqBtPasi9JLVmxntEv6smRszWDmCCUtK7rRfi4M9qwnvWPul\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 22, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 22, \"comments\": 9, \"content\": \"MAKLUMAN UMUM PENUTUPAN SEMENTARA JALAN SEMPENA PELANCARAN BULAN KEBANGSAAN DAN KIBAR JALUR GEMILANG PERINGKAT NEGERI PULAU PINANG TAHUN 2023#maklumanumum#PenutupanJalan#bulankebangsaan#mbpp\", \"posted_on\": \"2023-07-20T17:58:59.357644\", \"video\": [], \"image\": [\"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/361172746_697461372425416_5332850874216582082_n.jpg?stp=dst-jpg_p417x417&_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=wvApaAIQ3QwAX8wHcXj&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfC9wppLdM0WfRNF1ZZiv3-4jYZD0B-xQV1ge68WsD9fbQ&oe=64C58153\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/361647008_697461495758737_2268468754465571894_n.jpg?stp=dst-jpg_s600x600&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=ANgXVR1I-EwAX-RFVcA&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfCyvU7727eVDjjVHifv2bvNRNdMRII16xmqqsiEcomJNw&oe=64C516E9\", \"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/361600478_697461555758731_4380366494973922699_n.jpg?stp=dst-jpg_s600x600&_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=VN4Evx-XgZwAX8ygK0V&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfA43zWjHCovqWqrxdHNOJJ1xfAu8JlBBYjc2-spxOJcvg&oe=64C6832C\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02G7bt24Hq4vLiJ8e4MtqBtPasi9JLVmxntEv6smRszWDmCCUtK7rRfi4M9qwnvWPul?__cft__[0]=AZXTZY4yiAzvFgETy-SLU9ZxAqa2QdZMQnkY-w5pm7IseLpVMwFQku6NEMLi1n-rRVd5mCpuby63b0Xg9CevM_Je7_RcAktSguzaMcf4X0u3hUbtFzSpb2Ri0jRZq0vXX-1X3x9VJzEJTPpB7LCFVUp_JDTFbHXcGamVjCiRk-M5l_COlT_7jkiEC2D-_PQfKCvAoBHimcg5asSeYD2Bt_X7&__tn__=%2CO%2CP-R\"}, \"pfbid02m1KdmnwhyMv2fhhmvMRtPrcNtc1sxpatcS4vXvJN9nNoQX7vJAeYJmnoBbqjVRkjl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 1, \"reactions\": {\"likes\": 27, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 27, \"comments\": 1, \"content\": \"INFO POKOK TUMBANGJALAN JESSELTON 19 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-19T11:45:00\", \"video\": [], \"image\": [\"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/361949894_696939355810951_637653074382355264_n.jpg?stp=dst-jpg_s600x600&_nc_cat=106&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=av1aAelNis4AX_x3__N&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfBb5K07bWmaal0ZBPFHRxEf3EC2ZDunplCgw54Khbziug&oe=64C503B6\", \"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/361934450_696939402477613_5495853717864611386_n.jpg?stp=dst-jpg_s600x600&_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=IN1w-DkTCRwAX8Jje9T&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfCkyn4Ih5p0Q7oS7p69eXZTekjbW5Jnblq4slyaMiciFA&oe=64C6E2B8\", \"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/361924472_696939422477611_2299679787409325091_n.jpg?stp=dst-jpg_s600x600&_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=38X-2XFx12YAX_JjoXp&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfDoDFi520eS0CwX3Yy19p3ep1ThN-WJ0OFL0ZSvluV3xg&oe=64C66F72\", \"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/361621143_696939432477610_924132394406115068_n.jpg?stp=dst-jpg_s600x600&_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=xzYElwgqDVAAX-Kjeh9&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfBk5woQWg4gB-OAnRH4qR9qk8yxId4B7hErdiOZeFUyFQ&oe=64C537A4\", \"https://scontent.fsgn2-7.fna.fbcdn.net/v/t39.30808-6/361109008_696939445810942_6687869870241304905_n.jpg?stp=dst-jpg_s600x600&_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qfKQ1BCBYQ4AX-kxAN1&_nc_ht=scontent.fsgn2-7.fna&oh=00_AfAih1jyPtIyjcl3BEV2qVbyGnDnu2mdb9ZZJtFk80pDBw&oe=64C51F81\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02m1KdmnwhyMv2fhhmvMRtPrcNtc1sxpatcS4vXvJN9nNoQX7vJAeYJmnoBbqjVRkjl?__cft__[0]=AZUq-vMPRKc-jOtkKe-jbc2smeDUoQoBDefZqI9wSF0U75lZ0O-D_xnY2ZNaNLOr-Q9e_BSiXOS8BtIB-fmnON2zXz8hamnMew6FnWuNVJUd_-R1Ke6x-naA_NtQ6HFGURHElTmXUKnXYmvJWkF34FaPnTTM53ODnv-NawcYZ8TT7M1JQNJsZXh335BMMjq1WksazEHZ19GrYXHWUssxkku6&__tn__=%2CO%2CP-R\"}, \"pfbid02fKQ4KXtZNEVwb9PHpddZRNH58fciNU4p69cNfXWHVGTmRRd8AJaFE8gLiALb5Rfgl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 70, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 70, \"comments\": 0, \"content\": \"INFO POKOK TUMBANGJALAN PERMATANG DAMAR LAUT 19 Julai 2023 Syabas dan terima kasih kepada Skuad Pantas MBPP dari Jabatan Landskap yang menyegerakan kerja-kerja pemangkasan, pengalihan dan pembersihan pokok tumbang. Orang ramai dimohon untuk berhati-hati semasa berada di luar rumah dan sentiasa mengawasi ahli keluarga anda ketika keadaan cuaca yang tidak mengizinkan.Sebarang aduan mengenai banjir, tanah runtuh, pokok tumbang dan lain-lain, sila hubungi Hotline MBPP ditalian: 04-263 7000 / 04-263 7637016-2004082 (WhatsApp)#skuadpantas#mbpp #penang #pokoktumbang\", \"posted_on\": \"2023-07-19T11:34:00\", \"video\": [], \"image\": [\"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/361841600_696935159144704_2797509690449740069_n.jpg?stp=dst-jpg_s600x600&_nc_cat=109&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=EmCbiGVk_bMAX9ihXxp&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfDLW9ukyZ1nGJm21fMUeLgybMI5NEzrbb4uacXBw6ntZw&oe=64C68592\", \"https://scontent.fsgn2-3.fna.fbcdn.net/v/t39.30808-6/362021455_696935372478016_8453958619838799281_n.jpg?stp=dst-jpg_s600x600&_nc_cat=107&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=9RxUmIDP9koAX8BHDPv&_nc_ht=scontent.fsgn2-3.fna&oh=00_AfB0QeM3p4aVWEIq6ciXlE5wOOUGW9jLgM5pAJ47_EeYTw&oe=64C6257E\", \"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/361630728_696935442478009_5241826259459842902_n.jpg?stp=dst-jpg_p552x414&_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=ZzTrW0nG4EEAX9XJ53r&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfCvKnfuncayc8ydNJ8R-5iCRqD0o3gP4P55N5FnU-KJDw&oe=64C538C7\", \"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/361897200_696935539144666_5982647996762099050_n.jpg?stp=dst-jpg_p320x320&_nc_cat=104&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=HviyFh8dcEQAX_lMN8X&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfBICnPMPo9fUzSzRgYdGwjKhu2KW3dgIwxUfHW4jS332w&oe=64C4FDDB\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid02fKQ4KXtZNEVwb9PHpddZRNH58fciNU4p69cNfXWHVGTmRRd8AJaFE8gLiALb5Rfgl?__cft__[0]=AZUq85kEF884b1eOOupLLC0D_cGUfD4cj_i8uuyYtsNmKLZz_2DM7EM-Ts5m2Df0MmrSK5oUaLdmMMFWWE325UmqVKLB_YYVBKBxaAcRebReu-hV42zhlCXpV1WPGQGzq0Znn6v83g7XFvNLgVkUAwH9SaO93oU0Shki0NDv57K1ryfXgFht2KjH439ZeUnE1R9w_GSXbAveO2XKErERMWB_&__tn__=%2CO%2CP-R\"}, \"pfbid0g2TkHivt2aphDKrhsSoNBbhQJHnymehnxHdP9CL2x1wSGxLwH5U6c6pVqY74P8Sal\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 13, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 13, \"comments\": 0, \"content\": \"AMARAN RIBUT PETIR. Ribut petir, hujan lebat dan angin kencang dijangka di negeri Perlis \u2022 Kedah \u2022 Pulau Pinang \u2022 Perak (Kerian, Larut, Matang Dan Selama, Hulu Perak, Kuala Kangsar, Manjung dan Perak Tengah) sehingga 3:00 petang; Rabu, 19 Julai 2023.Amaran dikeluarkan apabila terdapat tanda-tanda menunjukkan ribut petir dengan intensiti hujan melebihi 20 mm/jam yang hampir ATAU dijangka berlaku melebihi sejam. Amaran ribut petir adalah amaran jangka pendek yang sah dalam tempoh tidak melebihi enam jam untuk satu-satu keluaran.Dikeluarkan pada: 11:50 pagi, 19 Julai 2023#ributpetirmetmalaysia#metmalaysia#NRECC#MalaysiaMADANI\", \"posted_on\": \"2023-07-19T11:29:00\", \"video\": [], \"image\": [\"https://scontent.fsgn2-5.fna.fbcdn.net/v/t39.30808-6/361663384_674025174767800_6162884616768083219_n.jpg?stp=dst-jpg_p180x540&_nc_cat=104&ccb=1-7&_nc_sid=730e14&_nc_ohc=vWJOLsv6rXQAX_82AjP&_nc_ht=scontent.fsgn2-5.fna&oh=00_AfABaSxwXWpt1VZ6nPbQzR7vNwe4GsCGxIkSC751uTE3ag&oe=64C6D417\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0g2TkHivt2aphDKrhsSoNBbhQJHnymehnxHdP9CL2x1wSGxLwH5U6c6pVqY74P8Sal?__cft__[0]=AZUgoK1Zu4T6p8x_p6mpJFKB7jwEQRk7NDjxslogedl3xxvFhHaMy_57-ekXUx6DJ5BmkjYuqrEzuYm9TQgLGL_IBQDPdaArys3dovVnVjOX1hS5TzT2FqrQ7o3RrfQxozhCK2jnzJvija-u3wdrcFrwRM6tD8NQ-hvU93J1UEhjfVB-zeN97FmLN4k2JPHxOMXW-exTHJYzZh54sbw2iB62eA25MjVTbfdPgZgBs6Kb-QJI_zhIWaPlAruiSt_h5I8&__tn__=%2CO%2CP-R\"}, \"pfbid06UmugEDE2xP8o9zRT4teXeGNLDvLcSqHEV8XhUXJSQHsJ2BqBBUBXFnHTWzurNrCl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 13, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 13, \"comments\": 1, \"content\": \"AMARAN RIBUT PETIR. Ribut petir, hujan lebat dan angin kencang dijangka di negeri Perlis \u2022 Kedah \u2022 Pulau Pinang \u2022 Perak (Kerian, Larut, Matang Dan Selama, Hulu Perak, Manjung, Perak Tengah, Bagan Datuk dan Hilir Perak) \u2022 Kelantan (Gua Musang) \u2022 Pahang (Tanah Tinggi Cameron, Lipis dan Jerantut) \u2022 Selangor (Sabak Bernam dan Kuala Selangor) \u2022 Johor (Pontian, Kulai, Kota Tinggi dan Johor Bahru) sehingga 12:00 tengah hari; Rabu, 19 Julai 2023.Amaran dikeluarkan apabila terdapat tanda-tanda menunjukkan ribut petir dengan intensiti hujan melebihi 20 mm/jam yang hampir ATAU dijangka berlaku melebihi sejam. Amaran ribut petir adalah amaran jangka pendek yang sah dalam tempoh tidak melebihi enam jam untuk satu-satu keluaran.Dikeluarkan pada: 8:50 pagi, 19 Julai 2023#ributpetirmetmalaysia#metmalaysia#NRECC#MalaysiaMADANI\", \"posted_on\": \"2023-07-19T08:10:00\", \"video\": [], \"image\": [\"https://scontent.fsgn2-6.fna.fbcdn.net/v/t39.30808-6/359820365_673960611440923_8917889804875379697_n.jpg?stp=dst-jpg_p180x540&_nc_cat=111&ccb=1-7&_nc_sid=730e14&_nc_ohc=-y_5nkpiGNwAX_MDpri&_nc_ht=scontent.fsgn2-6.fna&oh=00_AfBPw6FuCypVhR1Fd17Id5_Pd607-hjY8d8Fi78V-B1zXg&oe=64C64D34\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid06UmugEDE2xP8o9zRT4teXeGNLDvLcSqHEV8XhUXJSQHsJ2BqBBUBXFnHTWzurNrCl?__cft__[0]=AZVb7pUenGQZDAhiAJBJZ0PsUjWBIKwqO8Gj_VKH_b8IIGro3SmAJcsXdIFreZevraqxz3X0VGIqarrVpU657fcgpbhjS_mBdJDL3bUVE0YZz8qQGSXgZuGxKAypZzfdIr7ugyXazBPlBfXfhAoJf0T-rsiFTiymXlkja_NnxBiIzHxB-xyPxo42oJK9gs8wQGq-hgCl9enUMYlvy2cqp8ID-0Zm12e2BCSxnpkNGYdOsLnoweJzzIKQ6Z8b3W0J7Vk&__tn__=%2CO%2CP-R\"}, \"pfbid0kL6gvZb3RLv95hWh8JTWzqqdVBjSX5dVipfXJTd7ry3GHHyTM1s3utpppi8Vb9Al\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 3, \"reactions\": {\"likes\": 60, \"loves\": 5, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 65, \"comments\": 4, \"content\": \"SALAM MAAL HIJRAH KEPADA SEMUA UMAT ISLAM.1 MUHARRAM 1445 HIJRAH / 19 JULAI 2023 MASIHI #TAHUNBARUISLAM#maalhijrah\", \"posted_on\": \"2023-07-18T18:51:00\", \"video\": [], \"image\": [\"https://scontent.fsgn2-9.fna.fbcdn.net/v/t39.30808-6/361185956_696484765856410_2623582167112172370_n.jpg?stp=dst-jpg_s720x720&_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=_ALVBZYBHYcAX9eRWtH&_nc_ht=scontent.fsgn2-9.fna&oh=00_AfB-2tRns5mRPu9rbFtXUCvqPiuAPZGMxO3Q9Uz7Q2gnBw&oe=64C6C09B\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0kL6gvZb3RLv95hWh8JTWzqqdVBjSX5dVipfXJTd7ry3GHHyTM1s3utpppi8Vb9Al?__cft__[0]=AZU4CeGmmfb2RHuT1V6eIiMTthe-N82ttbQ0SHCzqSBR4Th-5UOLIz-nqiFIzRpnCGoa249rksQ388K15jZxZoo_TPUlTn0hubqnP8oDLUW2gwfWt3ahKxJ3ahU1OLvbzysaHTEvKPuQW6E5NysysGvKLwSBD5UEL0fAeNwJ1ElwLlAxpmDgtDLZaPWpdR1_NabzGwjUfo7Szg9lDTds0oaM&__tn__=%2CO%2CP-R\"}, \"pfbid0319viAe2Fk1AzrJ7QJZJsAwfjEUbXAbCYxfrRv8DoDyH4ss2BHiB3yXFJ6Yx3J95Cl\": {\"name\": \"Majlis Bandaraya Pulau Pinang - MBPP\", \"shares\": 0, \"reactions\": {\"likes\": 11, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 11, \"comments\": 1, \"content\": \"AMARAN RIBUT PETIR. Ribut petir, hujan lebat dan angin kencang dijangka di negeri Perlis \u2022 Kedah (Kubang Pasu, Kota Setar, Pokok Sena, Padang Terap, Yan, Pendang, Kuala Muda, Sik, Baling, Kulim dan Bandar Baharu) \u2022 Pulau Pinang \u2022 Pahang (Raub dan Bentong) \u2022 Selangor (Kuala Selangor dan Hulu Selangor) \u2022 Negeri Sembilan (Port Dickson, Rembau dan Tampin) \u2022 Melaka \u2022 Johor sehingga 9:00 pagi; Selasa, 18 Julai 2023.Amaran dikeluarkan apabila terdapat tanda-tanda menunjukkan ribut petir dengan intensiti hujan melebihi 20 mm/jam yang hampir ATAU dijangka berlaku melebihi sejam. Amaran ribut petir adalah amaran jangka pendek yang sah dalam tempoh tidak melebihi enam jam untuk satu-satu keluaran.Dikeluarkan pada: 6:10 pagi, 18 Julai 2023#ributpetirmetmalaysia#metmalaysia#NRECC#MalaysiaMADANI\", \"posted_on\": \"2023-07-18T06:49:00\", \"video\": [], \"image\": [\"https://scontent.fsgn2-4.fna.fbcdn.net/v/t39.30808-6/359792826_673378948165756_7378627215648239785_n.jpg?stp=dst-jpg_p180x540&_nc_cat=101&ccb=1-7&_nc_sid=730e14&_nc_ohc=KW3k3NgSg6EAX_8Nz_G&_nc_ht=scontent.fsgn2-4.fna&oh=00_AfAtoADj3JTP125V7XOprNipgg5VwyEiFt6gQQ65s2flUQ&oe=64C68DB5\"], \"post_url\": \"https://www.facebook.com/majlisbandaraya.pulaupinang/posts/pfbid0319viAe2Fk1AzrJ7QJZJsAwfjEUbXAbCYxfrRv8DoDyH4ss2BHiB3yXFJ6Yx3J95Cl?__cft__[0]=AZXy4a1d4qB22_s-AXF6Nx5RwT764MSKfDlcSCGF1aJLq0R20EDbEAMNBrrWBE4PHZH_Z4mRnQl2NPGPk74ZxJKPz_z-J-M2tdU-0OTnkjNdCvNQIedENPMSBPA55qn1FtNYl35SuZIM7bGT34YvtfLtozHWCkemq84m-KsqbG7P4rqBA1hVMVnFmSdMdRhUYyUnylUXWsyfJJYvD9aXdJVcP-4RqHN1g32BYOwBccPWh1d_8PJMM34WF4hJ4Q7Z2-g&__tn__=%2CO%2CP-R\"}}" \ No newline at end of file +"{\"pfbid0SbuUtKGAigprmuPARQyVpV7TYhuo4zUdM9ibSUm8YNRKu3MVxQoUAqfj7ghirGSHl\": {\"name\": \"FPT Software\", \"shares\": 1, \"reactions\": {\"likes\": 234, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 234, \"comments\": 1, \"content\": \" Strengthening cooperation promotion, expanding FPT Software\u2019s market in AustralasiaRecently, the Australian Embassy\u2019s Delegation visited Hola Park and had a working session with FPT Software\u2019s leaders. This is a chance for both sides to strengthen and develop strategic cooperation, as well as to promote business opportunities for FPT Software in the Australasia region. Mr. Andrew Goledzinowski \u2013 Australian Embassy to Vietnam and the delegation were welcomed by Ms. Chu Thi Thanh Ha \u2013 FPT Software\u2019s Chairwoman, Mr. Tran Hong Minh \u2013 CEO of FPT Australasia, and Ms. Do Kim Phuong \u2013 Director of Government Affairs. During the meeting, the Ambassador highly appreciates the significant achievements that FPT Software has accomplished in the Australian market. He also commits to actively promoting the company to Australian businesses, in order to generate more new cooperation opportunities.----- T\u0103ng c\u01b0\u1eddng x\u00fac ti\u1ebfn h\u1ee3p t\u00e1c, m\u1edf r\u1ed9ng th\u1ecb tr\u01b0\u1eddng FPT Software t\u1ea1i AustralasiaV\u1eeba qua \u0111o\u00e0n \u0111\u1ea1i s\u1ee9 \u00dac \u0111\u00e3 c\u00f3 chuy\u1ebfn th\u0103m v\u00e0 l\u00e0m vi\u1ec7c c\u00f9ng Ban l\u00e3nh \u0111\u1ea1o FPT Software t\u1ea1i Hola Park. \u0110\u00e2y l\u00e0 d\u1ecbp \u0111\u1ec3 hai b\u00ean c\u00f9ng c\u1ee7ng c\u1ed1 v\u00e0 ph\u00e1t tri\u1ec3n m\u1ed1i quan h\u1ec7 h\u1ee3p t\u00e1c chi\u1ebfn l\u01b0\u1ee3c, \u0111\u1ed3ng th\u1eddi th\u00fac \u0111\u1ea9y c\u01a1 h\u1ed9i kinh doanh c\u1ee7a FPT Software t\u1ea1i khu v\u1ef1c Australasia. \u0110\u00f3n ng\u00e0i \u0110\u1ea1i s\u1ee9 Andrew Goledzinowski v\u00e0 ph\u00e1i \u0111o\u00e0n l\u00e0 ch\u1ee7 t\u1ecbch FPT software Chu Th\u1ecb Thanh H\u00e0, CEO FPT Australasia Tr\u1ea7n H\u1ed3ng Minh, Gi\u00e1m \u0111\u1ed1c Quan h\u1ec7 Ch\u00ednh ph\u1ee7 FPT Software \u0110\u1ed7 Kim Ph\u01b0\u1ee3ng. Trong bu\u1ed5i g\u1eb7p, Ng\u00e0i \u0110\u1ea1i S\u1ee9 \u0111\u00e1nh gi\u00e1 cao nh\u1eefng th\u00e0nh t\u1ef1u \u0111\u00e1ng k\u1ec3 m\u00e0 FPT Software \u0111\u00e3 \u0111\u1ea1t \u0111\u01b0\u1ee3c t\u1ea1i th\u1ecb tr\u01b0\u1eddng Australia v\u00e0 cam k\u1ebft s\u1ebd \u0111\u1ea9y m\u1ea1nh vi\u1ec7c qu\u1ea3ng b\u00e1 c\u00f4ng ty v\u1edbi c\u00e1c doanh nghi\u1ec7p Australia, nh\u1eb1m t\u1ea1o ra th\u00eam nhi\u1ec1u c\u01a1 h\u1ed9i h\u1ee3p t\u00e1c m\u1edbi.\", \"posted_on\": \"2023-07-28T19:46:38.159781\", \"video\": [], \"image\": [\"https://scontent.fhan4-3.fna.fbcdn.net/v/t39.30808-6/363784302_666558112165755_1895772834461794167_n.jpg?stp=dst-jpg_p526x395&_nc_cat=100&ccb=1-7&_nc_sid=730e14&_nc_ohc=LFYLlL_k_0AAX86Qe8E&_nc_ht=scontent.fhan4-3.fna&oh=00_AfC0c8coCiZ_aTsY91caoN1k8JeHg5CwYG9SyAskmDDwHg&oe=64CB88C9\", \"https://scontent.fhan3-4.fna.fbcdn.net/v/t39.30808-6/363805548_666558205499079_2281794607103759271_n.jpg?stp=dst-jpg_p600x600&_nc_cat=106&ccb=1-7&_nc_sid=730e14&_nc_ohc=y4puAX-zfs4AX-Yd5mx&_nc_ht=scontent.fhan3-4.fna&oh=00_AfC2Y59lKZSgsnTQuPCpNKbLQX7XYTi4sFQvi-pheJIohw&oe=64CBD677\", \"https://scontent.fhan3-1.fna.fbcdn.net/v/t39.30808-6/363816652_666558195499080_4789558155526936456_n.jpg?stp=dst-jpg_p600x600&_nc_cat=102&ccb=1-7&_nc_sid=730e14&_nc_ohc=RlJFnaa6FU4AX_Kp5_1&_nc_ht=scontent.fhan3-1.fna&oh=00_AfD5Q1l1k6S-qjW9lzmnW38Y16kOc44oU1gGo4iPoZX33w&oe=64CA7B03\", \"https://scontent.fhan3-5.fna.fbcdn.net/v/t39.30808-6/363332892_666558288832404_7230856333676365522_n.jpg?stp=dst-jpg_p600x600&_nc_cat=109&ccb=1-7&_nc_sid=730e14&_nc_ohc=1b_Qy939oJ8AX_IhoCs&_nc_ht=scontent.fhan3-5.fna&oh=00_AfATJ6iu9vW3urkVOD7_l7ASWj0QVZ8UySHgTzQ5uNq59w&oe=64CBA78C\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0SbuUtKGAigprmuPARQyVpV7TYhuo4zUdM9ibSUm8YNRKu3MVxQoUAqfj7ghirGSHl?__cft__[0]=AZW8AJPrE9O0fNCNvCDRsTTBtFMK7-Dj_z2Gyf8dlZouwdl77w2Jjpa108jMJyTq2J8K5B1d0ACQqzhJpmm1fm5p1wBz2csxBlmp1RU6AXE5yF73kBeJtl8Sc7NAoNgS4RSKgbrc-emgoZl8sV7wuYYlVqwtrg1SvM2J2zBEoW5liKgAD1OtSOGP_u-50RTaF1uSRZljp3EYxNfYbmu89WGH&__tn__=%2CO%2CP-R\"}, \"pfbid028gYzhYByq9Jch9uKFh6DkSTsvrHvScimAV2uKmZ4GecsK1vof5PvVxkzSXktKwUyl\": {\"name\": \"FPT Software\", \"shares\": 0, \"reactions\": {\"likes\": 40, \"loves\": 9, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 49, \"comments\": 1, \"content\": \" The talented young Solutions Architect of FPT Software - Khanh NghiemKhanh Nghiem began his career at Google Cloud as a Cloud Technical Resident in the talent training program. He then became a Technical Account Manager for the Finance/Banking group in the North American region, specializing in Cloud Infrastructure, Collaboration & Productivity. After three years at Google, Khanh made a strategic move to FPT Software, assuming the position of Solutions Architect. He and the AI4Code team are jointly developing and deploying the Coding Assistant project - a comprehensive tool designed to provide holistic support to programmers. This cutting-edge project is expected to enable FPT Software to swiftly adopt the most advanced AI language models, catering not only to specific needs but also ensuring maximum data security for the company and its clients.----- Ki\u1ebfn tr\u00fac s\u01b0 gi\u1ea3i ph\u00e1p tr\u1ebb t\u00e0i n\u0103ng c\u1ee7a FPT Software - Kh\u00e1nh Nghi\u00eamKh\u00e1nh Nghi\u00eam \ufe0fkh\u1edfi \u0111\u1ea7u s\u1ef1 nghi\u1ec7p c\u1ee7a m\u00ecnh t\u1ea1i Google Cloud trong ch\u01b0\u01a1ng tr\u00ecnh \u0111\u00e0o t\u1ea1o t\u00e0i n\u0103ng Cloud Technical Resident. V\u00e0 sau \u0111\u00f3 tr\u1edf th\u00e0nh Technical Account Manager cho nh\u00f3m t\u1eadp \u0111o\u00e0n T\u00e0i ch\u00ednh/Ng\u00e2n h\u00e0ng khu v\u1ef1c B\u1eafc M\u1ef9, v\u1edbi chuy\u00ean m\u00f4n v\u1ec1 Cloud Infrastructure, Collaboration & Productivity. Sau 3 n\u0103m l\u00e0m vi\u1ec7c t\u1ea1i Google, Kh\u00e1nh \u0111\u1ea7u qu\u00e2n cho FPT Software v\u1edbi v\u1ecb tr\u00ed Ki\u1ebfn tr\u00fac s\u01b0 gi\u1ea3i ph\u00e1p. Anh v\u00e0 nh\u00f3m AI4Code \u0111ang c\u00f9ng nhau x\u00e2y d\u1ef1ng v\u00e0 tri\u1ec3n khai d\u1ef1 \u00e1n Coding Assistant - c\u00f4ng c\u1ee5 h\u1ed7 tr\u1ee3 l\u1eadp tr\u00ecnh vi\u00ean to\u00e0n n\u0103ng. D\u1ef1 \u00e1n \u0111\u01b0\u1ee3c k\u1ef3 v\u1ecdng gi\u00fap FPT Software nhanh ch\u00f3ng \u1ee9ng d\u1ee5ng \u0111\u01b0\u1ee3c nh\u1eefng m\u00f4 h\u00ecnh AI ng\u00f4n ng\u1eef ti\u00ean ti\u1ebfn nh\u1ea5t, kh\u00f4ng ch\u1ec9 \u0111i s\u00e1t v\u1edbi nhu c\u1ea7u \u0111\u1eb7c th\u00f9 m\u00e0 c\u00f2n \u0111\u1ea3m b\u1ea3o tuy\u1ec7t \u0111\u1ed1i b\u1ea3o m\u1eadt d\u1eef li\u1ec7u cho doanh nghi\u1ec7p, kh\u00e1ch h\u00e0ng.\", \"posted_on\": \"2023-07-27T19:46:44.819794\", \"video\": [], \"image\": [\"https://scontent.fhan3-2.fna.fbcdn.net/v/t39.30808-6/363763880_666417648846468_6211449970306198338_n.jpg?stp=dst-jpg_p180x540&_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=ND7Y-b10D-0AX9kdjeI&_nc_ht=scontent.fhan3-2.fna&oh=00_AfDw6vGPt7x6xsKYG700Rh1IlbQDKhzQJu-bzC8SlzmVmw&oe=64CAF9E4\", \"https://static.xx.fbcdn.net/rsrc.php/v3/yw/r/8iuTX4LlGZO.png\", \"https://external.fhan3-5.fna.fbcdn.net/emg1/v/t13/1172482651598332873?url=https%3A%2F%2Fvcdn1-sohoa.vnecdn.net%2F2023%2F07%2F26%2FImage-551715486-ExtractWord-0-9464-2725-1690354261.png%3Fw%3D1200%26h%3D0%26q%3D100%26dpr%3D1%26fit%3Dcrop%26s%3D9TiYmAPhsxI8jCEG7vQl-A&fb_obo=1&utld=vnecdn.net&stp=c0.5000x0.5000f_dst-emg0_p98x98_q75&ccb=13-1&oh=06_AbEJcWp-W4Op6sV5RjQLmcxjJCWAjUD-4xeQDi58bA0-DA&oe=64C82085&_nc_sid=dbad39\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid028gYzhYByq9Jch9uKFh6DkSTsvrHvScimAV2uKmZ4GecsK1vof5PvVxkzSXktKwUyl?__cft__[0]=AZU4s_JVre8DQK7XTdCrb-B8Wchd92DSEiNUk-4GFTdZU-yx_IHqFNNKN1-sf7wNoqDPhW3airOeNNYb2lgx7tHuwD8Dr4s2y5rDK02Yc9rMlzspW57BOVuPddLhlJfh3O1mjfqgXG_XKcPrGn8m3YdUZL_EL_DJcNpAodkz7NjMsYoSgR_ATtadFjrNPHSpuM2N_tNWmWU-ZG96i4qG_CaU&__tn__=%2CO%2CP-R\"}, \"pfbid0YGC3bXzhPzatNRYLMpjg3mPsRSTUuh1ZRUVa6TshspGZnzGeXQk7VcEQfeevo6n1l\": {\"name\": \"FPT Software\", \"shares\": 2, \"reactions\": {\"likes\": 73, \"loves\": 25, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 98, \"comments\": 17, \"content\": \" Phung Viet Ha, the leader of a series of million-dollar technology projects.Viet Ha started his management role since he was a student. While studying at FPT University Hanoi, he took on the role of Deputy Head of the volunteer student club. Up to now, the male engineer has become the Director of Low-code Group, managing a team of top experts at FPT Software. From 8 million USD, Low-code Group has achieved a record revenue of up to 34 million USD, an increase of over 400% during the period of 2021-2022. Speaking about this success, Ha shared that building a talented and cohesive team is the way he conquers projects ranging from small to multimillion-dollar ones.----- Ph\u00f9ng Vi\u1ebft H\u00e0, th\u1ee7 l\u0129nh c\u1ee7a m\u1ed9t lo\u1ea1t d\u1ef1 \u00e1n c\u00f4ng ngh\u1ec7 tr\u1ecb gi\u00e1 tri\u1ec7u \u0111\u00f4Vi\u1ebft H\u00e0 b\u1eaft \u0111\u1ea7u vai tr\u00f2 qu\u1ea3n l\u00fd t\u1eeb th\u1eddi \u0111i h\u1ecdc. Khi c\u00f2n h\u1ecdc t\u1ea1i Tr\u01b0\u1eddng \u0110\u1ea1i h\u1ecdc FPT H\u00e0 N\u1ed9i, anh \u0111\u1ea3m nh\u1eadn vai tr\u00f2 Ph\u00f3 ch\u1ee7 nhi\u1ec7m c\u00e2u l\u1ea1c b\u1ed9 sinh vi\u00ean t\u00ecnh nguy\u1ec7n. \u0110\u1ebfn nay, nam k\u1ef9 s\u01b0 \u0111\u00e3 tr\u1edf th\u00e0nh Gi\u00e1m \u0111\u1ed1c Low-code Group, qu\u1ea3n l\u00fd nh\u00e2n s\u1ef1 g\u1ed3m nhi\u1ec1u chuy\u00ean gia h\u00e0ng \u0111\u1ea7u c\u1ee7a FPT Software. T\u1eeb 8 tri\u1ec7u USD, Low-code Group \u0111\u00e3 \u0111\u1ea1t k\u1ef7 l\u1ee5c doanh thu l\u00ean t\u1edbi 34 tri\u1ec7u USD t\u0103ng h\u01a1n 400% trong giai \u0111o\u1ea1n 2021-2022. N\u00f3i v\u1ec1 th\u00e0nh c\u00f4ng n\u00e0y, anh H\u00e0 chia s\u1ebb c\u00e1ch \u0111\u1ec3 anh chinh ph\u1ee5c c\u00e1c d\u1ef1 \u00e1n t\u1eeb nh\u1ecf \u0111\u1ebfn h\u00e0ng tri\u1ec7u USD l\u00e0 x\u00e2y d\u1ef1ng \u0111\u01b0\u1ee3c m\u1ed9t \u0111\u1ed9i nh\u00f3m tinh nhu\u1ec7 v\u00e0 chung ch\u00ed h\u01b0\u1edbng.\", \"posted_on\": \"2023-07-26T19:46:45.273713\", \"video\": [], \"image\": [\"https://scontent.fhan3-5.fna.fbcdn.net/v/t39.30808-6/363326364_665874335567466_4012627672933344767_n.jpg?stp=dst-jpg_p180x540&_nc_cat=109&ccb=1-7&_nc_sid=730e14&_nc_ohc=UQby1bkSqP4AX_hX7G4&_nc_ht=scontent.fhan3-5.fna&oh=00_AfA95BYjnRJ81WGiLC0JgZibicuzCmtToElg0JqoaLSQVA&oe=64CBABD2\", \"https://static.xx.fbcdn.net/rsrc.php/v3/yw/r/8iuTX4LlGZO.png\", \"https://external.fhan3-5.fna.fbcdn.net/emg1/v/t13/5348722827683182679?url=https%3A%2F%2Fi2-vnexpress.vnecdn.net%2F2023%2F07%2F24%2Fimage001-1690196269-4174-1690196298.jpg%3Fw%3D1200%26h%3D0%26q%3D100%26dpr%3D1%26fit%3Dcrop%26s%3Dg8dg973o_IqJG2Yf5sc-Zw&fb_obo=1&utld=vnecdn.net&stp=c0.5000x0.5000f_dst-emg0_p98x98_q75&ccb=13-1&oh=06_AbHHZu0HPvkgIixoXZ6Sg5T1ZsJUlJqXEZDn1iHw4TZh7w&oe=64C7F7DB&_nc_sid=dbad39\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0YGC3bXzhPzatNRYLMpjg3mPsRSTUuh1ZRUVa6TshspGZnzGeXQk7VcEQfeevo6n1l?__cft__[0]=AZVHHLSsYifb_bhyUX6-K7SneXscnO_nJ7Tbjr3myEiYp-Zl01m3l0K7K1x9HocnPaqv0DbzCPavpqBKk8jQHc161tsS9UKjoDRxzQDc-SdTmSqgnvy5bA-sS5dN7ZvojnTs0FhGFocRAUjAqQnhb3GxGfj-aM5ah0GGwQp3cy8KWcYq4O5EEz3nOST3cZ-c1Oo0Jz1OwtMzKfGBAW-9mF8p&__tn__=%2CO%2CP-R\"}, \"pfbid0sQe3xG974KwVJjvVG1vACvPNvC43BHbp3A8wBfKtHtNdwUHRpCWEQRkfr8V4uhTdl\": {\"name\": \"FPT Software\", \"shares\": 4, \"reactions\": {\"likes\": 39, \"loves\": 10, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 49, \"comments\": 1, \"content\": \" What's special about FPT Software's new office in Hue? Officially inaugurated on July 21st, the office in Hue is designed in line with the CodeCation spirit that FPT Software is pursuing, featuring full utilities and an open space concept, integrated with various green areas. This setup provides a relaxed working environment, fostering creativity and boosting productivity for employees.----- C\u00f3 g\u00ec \u1edf \u0111\u1eb7c bi\u1ec7t \u1edf V\u0103n ph\u00f2ng m\u1edbi c\u1ee7a FPT Software t\u1ea1i Hu\u1ebf?Ch\u00ednh th\u1ee9c khai tr\u01b0\u01a1ng v\u00e0o ng\u00e0y 21/7 v\u1eeba qua, v\u0103n ph\u00f2ng \u1edf Hu\u1ebf \u0111\u01b0\u1ee3c thi\u1ebft k\u1ebf \u0111\u00fang theo tinh th\u1ea7n CodeCation m\u00e0 FPT Software \u0111ang theo \u0111u\u1ed5i v\u1edbi \u0111\u1ea7y \u0111\u1ee7 ti\u1ec7n \u00edch c\u00f9ng kh\u00f4ng gian m\u1edf, t\u00edch h\u1ee3p nhi\u1ec1u m\u1ea3ng xanh, v\u1eeba mang l\u1ea1i tr\u1ea3i nghi\u1ec7m l\u00e0m vi\u1ec7c th\u01b0 th\u00e1i v\u1eeba th\u00fac \u0111\u1ea9y hi\u1ec7u su\u1ea5t s\u00e1ng t\u1ea1o cho nh\u00e2n vi\u00ean.\", \"posted_on\": \"2023-07-25T19:46:46.361511\", \"video\": [\"blob:https://www.facebook.com/cc99c811-16f0-41e7-be8a-6e9752cf29c0\"], \"image\": [\"https://scontent.fhan3-2.fna.fbcdn.net/v/t15.5256-10/361826707_1236405180363650_5750175704385242735_n.jpg?stp=dst-jpg_p180x540&_nc_cat=107&ccb=1-7&_nc_sid=ad6a45&_nc_ohc=mx_VBBXH4VQAX_8BDh2&_nc_ht=scontent.fhan3-2.fna&oh=00_AfDMnjiHc0V1X2Mbu2J3mPZWYIxKO1__dcwCZcOIkgliWQ&oe=64CB2720\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\", \"https://scontent.fhan3-5.fna.fbcdn.net/v/t39.1997-6/47270791_937342239796388_4222599360510164992_n.png?stp=cp0_dst-png_s110x80&_nc_cat=1&ccb=1-7&_nc_sid=ac3552&_nc_ohc=HtNbGHHnysIAX8STUFd&_nc_ht=scontent.fhan3-5.fna&oh=00_AfAdMJPzqSifMydlvE7yqCMKC8P--CDhXUlNsdzkhAdCig&oe=64CBDAF2\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0sQe3xG974KwVJjvVG1vACvPNvC43BHbp3A8wBfKtHtNdwUHRpCWEQRkfr8V4uhTdl?__cft__[0]=AZU3SWvHxHWFo1iunOlOJDNC7Gs9DgC8LdIg9GnSpuBjMbv1r03KZ96NyQPl7XHePvvf0WD3uN1XjcaIVj6CctoHU03xzvBr8JWQup7mJIJVHuiYeu6lSw8I8Nu_cZi7Hkaq1p1LYGjQGET6xoOgyuk7J1o9xpIOMWuBr6_jLNRQFlWFYeVCM-XlNvfTsW7gDv-BTikoco5WURpLy4Kh_PGB&__tn__=%2CO%2CP-R\"}, \"pfbid0P4osyhsREuhWWfDjHM8mKjauw6yPhgZDrMk7hgBJSCFGV3GCB9T3mB1mS2xvEkenl\": {\"name\": \"FPT Software\", \"shares\": 8, \"reactions\": {\"likes\": 477, \"loves\": 38, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 515, \"comments\": 11, \"content\": \" FPT Software accompanies Google Developer Group at one of the most anticipated technology events of the year Last weekend, Google I/O Extended Hanoi 2023, an extended event from Google I/O in the US, was held in Hanoi, attracting over 1,000 attendees with more than 15 expert speakers from Google and leading technology companies. At this year's event, Speaker Khanh Nghiem, Solution Architect from FPT Software AI Center, had a presentation on AI-powered developer tools. He not only provided an overview of the global AI tool landscape for programmers and how to maximize the benefits from these tools but also introduced AI technology products that are currently being developed and implemented at FPT Software, including Docify AI.----- FPT Software \u0111\u1ed3ng h\u00e0nh c\u00f9ng Google Developer Group t\u1ea1i m\u1ed9t trong nh\u1eefng s\u1ef1 ki\u1ec7n c\u00f4ng ngh\u1ec7 \u0111\u01b0\u1ee3c mong ch\u1edd nh\u1ea5t trong n\u0103mCu\u1ed1i tu\u1ea7n qua, Google I/O Extended Hanoi 2023, s\u1ef1 ki\u1ec7n m\u1edf r\u1ed9ng t\u1eeb Google I/O t\u1ea1i M\u1ef9 \u0111\u00e3 \u0111\u01b0\u1ee3c t\u1ed5 ch\u1ee9c t\u1ea1i H\u00e0 N\u1ed9i, thu h\u00fat h\u01a1n 1.000 ng\u01b0\u1eddi tham d\u1ef1 v\u1edbi h\u01a1n 15 di\u1ec5n gi\u1ea3 chuy\u00ean gia \u0111\u1ebfn t\u1eeb Google v\u00e0 c\u00e1c c\u00f4ng ty c\u00f4ng ngh\u1ec7 h\u00e0ng \u0111\u1ea7u. \u0110\u1ebfn v\u1edbi ch\u01b0\u01a1ng tr\u00ecnh n\u0103m nay, Kh\u00e1nh Nghi\u00eam, Solution Architect c\u1ee7a FPT Software AI Center \u0111\u00e3 c\u00f3 b\u00e0i chia s\u1ebb v\u1ec1 c\u00f4ng c\u1ee5 AI t\u1ed1i \u01b0u h\u00f3a l\u1eadp tr\u00ecnh. Kh\u00f4ng ch\u1ec9 mang \u0111\u1ebfn c\u00e1i nh\u00ecn t\u1ed5ng quan v\u1ec1 to\u00e0n c\u1ea3nh c\u00f4ng c\u1ee5 AI cho l\u1eadp tr\u00ecnh vi\u00ean tr\u00ean th\u1ebf gi\u1edbi v\u00e0 c\u00e1ch khai th\u00e1c t\u1ed1i \u0111a l\u1ee3i \u00edch t\u1eeb nh\u1eefng c\u00f4ng c\u1ee5 n\u00e0y, Kh\u00e1nh c\u00f2n gi\u1edbi thi\u1ec7u v\u1ec1 c\u00e1c s\u1ea3n ph\u1ea9m c\u00f4ng ngh\u1ec7 \u1ee9ng d\u1ee5ng AI \u0111ang \u0111\u01b0\u1ee3c tri\u1ec3n khai x\u00e2y d\u1ef1ng t\u1ea1i FPT Software trong \u0111\u00f3 c\u00f3 Docify AI.\", \"posted_on\": \"2023-07-24T19:46:52.192423\", \"video\": [], \"image\": [\"https://scontent.fhan4-3.fna.fbcdn.net/v/t39.30808-6/362669158_664865179001715_540109131676132038_n.jpg?stp=dst-jpg_p526x395&_nc_cat=103&ccb=1-7&_nc_sid=730e14&_nc_ohc=iUN5G5nECesAX8Ak9ct&_nc_ht=scontent.fhan4-3.fna&oh=00_AfA_molJRoSygr2CaRSU557PdVZeSTUbZgytwMZuXOF10Q&oe=64CC057D\", \"https://scontent.fhan3-1.fna.fbcdn.net/v/t39.30808-6/362683145_664826629005570_8576407252050863510_n.jpg?stp=dst-jpg_p600x600&_nc_cat=102&ccb=1-7&_nc_sid=730e14&_nc_ohc=8J4-RB_Z-ygAX-oqWNR&_nc_ht=scontent.fhan3-1.fna&oh=00_AfCDdrtUQ1r_cq83wZ4J8epjvA7wF6RjwCevubDeZcVldw&oe=64CC3B1C\", \"https://scontent.fhan4-3.fna.fbcdn.net/v/t39.30808-6/362671147_664826479005585_8277228697336227486_n.jpg?stp=dst-jpg_p600x600&_nc_cat=100&ccb=1-7&_nc_sid=730e14&_nc_ohc=qwqIbaVKhmUAX9prvTU&_nc_ht=scontent.fhan4-3.fna&oh=00_AfDILOnx3EwHEsc7mk-76KIpbh-eVR3z26euF9t1GnOAag&oe=64CAF0B1\", \"https://scontent.fhan3-5.fna.fbcdn.net/v/t39.30808-6/362669963_664826439005589_7897632609104316856_n.jpg?stp=dst-jpg_p600x600&_nc_cat=109&ccb=1-7&_nc_sid=730e14&_nc_ohc=spwEVVb8XNEAX8MfdRh&_nc_ht=scontent.fhan3-5.fna&oh=00_AfB3ata3cMOo4JVkOlNcOF9x9Tclz0oy7s9qIfSD_n7daA&oe=64CC2550\", \"https://scontent.fhan3-5.fna.fbcdn.net/v/t39.1997-6/106254925_953856331743391_5331504226039302019_n.png?stp=dst-png_p240x240&_nc_cat=1&ccb=1-7&_nc_sid=0572db&_nc_ohc=at2GvQBuo1UAX8NpxSP&_nc_ht=scontent.fhan3-5.fna&oh=00_AfAF7KbDXcpSwfzXAeadEyQiTq_H1xAxdpk-c4ixKD_GqA&oe=64CB57AC\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0P4osyhsREuhWWfDjHM8mKjauw6yPhgZDrMk7hgBJSCFGV3GCB9T3mB1mS2xvEkenl?__cft__[0]=AZXkkrV2ntIZ2biG6B1ZzATUhEzaxdfwD9wvjczPl1L9f7bQtH8TakHOy19ffIlKoBPvGu6gV_T-AmoTwgHKWvs3HyW7T_hNTPejawQieud2N5bqEnLvPLr1ivWSGSYhdljstB7Ikky41rLQXeywtO-5qgmbB5Ctnoowf5dMOICaBrixae_NmBEE9UyHxLWFxzwLOZyXbcU5TfkhCaUNPhz7&__tn__=%2CO%2CP-R\"}, \"pfbid0219AZ8cqVsfztp57zW2t3oSZpNrzkrcoFzAvGpdrMUdphuis1iJYtLDXhwjoBHAzfl\": {\"name\": \"FPT Software\", \"shares\": 0, \"reactions\": {\"likes\": 24, \"loves\": 7, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 10}, \"reaction_count\": 41, \"comments\": 2, \"content\": \"We will be back with the breaking news. Thanks for following #FPTSoftware.Here are some notable news from the past week:FSOFT Hue branch officially openedMCP launched Marketing HubFPT Software Academy's headquarter moves to a new locationFJP organizes Company Trip connecting the entire company#News\", \"posted_on\": \"2023-07-24T19:46:52.635321\", \"video\": [\"blob:https://www.facebook.com/bb84cb46-a872-46e8-a5d2-4edeec3801b0\"], \"image\": [\"https://scontent.fhan4-3.fna.fbcdn.net/v/t15.5256-10/362443484_821654812571651_4703277646518272377_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=ad6a45&_nc_ohc=-ljaKTaI1PoAX9LDcDu&_nc_ht=scontent.fhan4-3.fna&oh=00_AfAKj8YQCQ7NfTlTAVyHP4zXfYQzcaohXqsHlwrRVewtog&oe=64CB87D2\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0219AZ8cqVsfztp57zW2t3oSZpNrzkrcoFzAvGpdrMUdphuis1iJYtLDXhwjoBHAzfl?__cft__[0]=AZVnzd2yIv9r7Dphmb0OqvMJmUwKMbuHR94iq5s_VwBjwmrAJ0txPZWvsEtdoCHmsJm6mA_cKqqBgHnVuylD7bnubD9kOnFyiZlyLv-AuHxtnhI3NxLanNh42sPrGbisVj0Amtnu-E09Yq-oVgQ27Kq9q2qcNdzjEEVRwVCX5TgC4uIPZZWKRsK6O1WPRpjF71qrlTxAZWOtsDMIIjjw_jA8&__tn__=%2CO%2CP-R\"}, \"pfbid0WeVK9eS4rbdNegt2BWBF3yLWwUnc8EpDQXqx9k9gEfQsddK4usszsK2e4ZX4ya3el\": {\"name\": \"FPT Software\", \"shares\": 1, \"reactions\": {\"likes\": 19, \"loves\": 6, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 25, \"comments\": 1, \"content\": \" FPT Software opens a new office in Hue This morning, FPT Software officially opened new office in the center of Hue. The inauguration ceremony was attended by Mr. Phan Ngoc Tho, Deputy Secretary of the Provincial Party Committee, Mr. Phan Thien Dinh, Standing Member of Provincial Party Committee, Secretary of Hue City Party Committee, Mr. Phan Quy Phuong - Vice Chairman of the Provincial People's Committee, and Ms. Chu Thi Thanh Ha - Chairwoman of FPT Software.With the message \\\"Open Another World,\\\" FPT Software expects to use technology to bring positive changes to the ancient capital region. This is the 4th office of the company in the Central region, following Da Nang, Quang Nam, and Quy Nhon, with an estimated 1000 employees by 2025 and a fully equipped office with 2000 seats by 2026. ----- FPT Software khai tr\u01b0\u01a1ng v\u0103n ph\u00f2ng m\u1edbi t\u1ea1i Hu\u1ebf S\u00e1ng nay ng\u00e0y 21/7, FPT Software ch\u00ednh th\u1ee9c khai tr\u01b0\u01a1ng v\u0103n ph\u00f2ng m\u1edbi t\u1ea1i trung t\u00e2m th\u00e0nh ph\u1ed1 Hu\u1ebf. Bu\u1ed5i l\u1ec5 c\u00f3 s\u1ef1 tham d\u1ef1 c\u1ee7a \u00f4ng Phan Ng\u1ecdc Th\u1ecd Ph\u00f3 B\u00ed th\u01b0 th\u01b0\u1eddng tr\u1ef1c T\u1ec9nh \u1ee6y, \u00f4ng Phan Thi\u00ean \u0110\u1ecbnh \u2013 UVTV T\u1ec9nh \u1ee7y, B\u00ed th\u01b0 Th\u00e0nh \u1ee7y, Phan Qu\u00fd Ph\u01b0\u01a1ng \u2013 Ph\u00f3 Ch\u1ee7 t\u1ecbch UBND T\u1ec9nh, v\u00e0 b\u00e0 Chu Th\u1ecb Thanh H\u00e0 Ch\u1ee7 t\u1ecbch c\u00f4ng ty FPT Software.V\u1edbi th\u00f4ng \u0111i\u1ec7p \u201cOpen Another World\u201d, FPT Software k\u1ef3 v\u1ecdng s\u1ebd d\u00f9ng c\u00f4ng ngh\u1ec7 \u0111\u1ec3 t\u1ea1o ra nh\u1eefng thay \u0111\u1ed5i t\u00edch c\u1ef1c cho v\u00f9ng \u0111\u1ea5t c\u1ed1 \u0111\u00f4. \u0110\u00e2y l\u00e0 v\u0103n ph\u00f2ng th\u1ee9 4 c\u1ee7a c\u00f4ng ty t\u1ea1i khu v\u1ef1c mi\u1ec1n Trung, sau \u0110\u00e0 N\u1eb5ng, Qu\u1ea3ng Nam v\u00e0 Quy Nh\u01a1n, d\u1ef1 ki\u1ebfn s\u1ebd c\u00f3 1000 nh\u00e2n s\u1ef1 v\u00e0o n\u0103m 2025 v\u00e0 ho\u00e0n thi\u1ec7n v\u0103n ph\u00f2ng 2000 ch\u1ed7 ng\u1ed3i v\u00e0o n\u0103m 2026.\", \"posted_on\": \"2023-07-21T19:30:00\", \"video\": [], \"image\": [\"https://scontent.fhan4-3.fna.fbcdn.net/v/t39.30808-6/362229095_663164835838416_3929841453660426578_n.jpg?stp=dst-jpg_p526x395&_nc_cat=103&ccb=1-7&_nc_sid=730e14&_nc_ohc=tK4PWb0kX64AX_02RGY&_nc_ht=scontent.fhan4-3.fna&oh=00_AfBbZBGeth8uQp517b_oC31JKABNMTdqoeF3FACuB2gI-w&oe=64CA8098\", \"https://scontent.fhan4-2.fna.fbcdn.net/v/t39.30808-6/362283169_663165089171724_1637712420652623425_n.jpg?stp=dst-jpg_p600x600&_nc_cat=111&ccb=1-7&_nc_sid=730e14&_nc_ohc=udXjvSDB2FgAX8znVF2&_nc_ht=scontent.fhan4-2.fna&oh=00_AfBBxiZk1YFv-XWV_W9pRV6_-QzZw2Q9r_psu6KViYYOAw&oe=64CA5458\", \"https://scontent.fhan3-4.fna.fbcdn.net/v/t39.30808-6/362606548_663165809171652_6428006275087871845_n.jpg?stp=dst-jpg_p600x600&_nc_cat=106&ccb=1-7&_nc_sid=730e14&_nc_ohc=oxhp5DLBkcgAX_G6-3l&_nc_ht=scontent.fhan3-4.fna&oh=00_AfCA8tb0__sxNZsa49MJrfNgF0DzkdzxHVs2BSuD_OFNnA&oe=64CB8204\", \"https://scontent.fhan4-1.fna.fbcdn.net/v/t39.30808-6/362296980_663165079171725_3766220148413329954_n.jpg?stp=dst-jpg_p600x600&_nc_cat=105&ccb=1-7&_nc_sid=730e14&_nc_ohc=1dFC_lmChjcAX93Jm3w&_nc_ht=scontent.fhan4-1.fna&oh=00_AfATwV6PzuNdLk_weSYWXJbx5OmGCpGnnCM-tMiB5fWA-g&oe=64CC38AC\", \"https://static.xx.fbcdn.net/rsrc.php/v3/yw/r/8iuTX4LlGZO.png\", \"https://external.fhan3-5.fna.fbcdn.net/emg1/v/t13/6452145814268286802?url=https%3A%2F%2Fvcdn1-kinhdoanh.vnecdn.net%2F2023%2F07%2F21%2Fimage002-3997-1689937223.jpg%3Fw%3D1200%26h%3D0%26q%3D100%26dpr%3D1%26fit%3Dcrop%26s%3DydTtLzxAB9QGNj7Av4lWPg&fb_obo=1&utld=vnecdn.net&stp=c0.5000x0.5000f_dst-emg0_p98x98_q75&ccb=13-1&oh=06_AbHE7I6R8dHDQwxLXdRJEgVFYcKtJ3hP1hQhnn68Og5KBQ&oe=64C7C45F&_nc_sid=dbad39\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0WeVK9eS4rbdNegt2BWBF3yLWwUnc8EpDQXqx9k9gEfQsddK4usszsK2e4ZX4ya3el?__cft__[0]=AZW47OW-XrZjsK5cwL2kx48AxUedpIbJbruD8HTXxhpeJmw1e2KKS69HBDn1BoV39ymu_gEX-nH2NDrRQDLhx6Icskrf7x2AyJpALA4xGOrBPlkmeg0YnYXuyBBCBDbWyoDyEcxdP2IJdzaZz94IXjV_1zm1iqfIEtrKighFS_1CrL3GmM7LoQGm6gW4Uz85rYg1paTZZC5KYng1xBN6q1t_&__tn__=%2CO%2CP-R\"}, \"pfbid0J5cxK3LCvDedaqQmXxU9tdSs7oijLZbQJK7BQ2CMBgvin2fc77Ytdp5Ymp5cah6jl\": {\"name\": \"FPT Software\", \"shares\": 10, \"reactions\": {\"likes\": 47, \"loves\": 14, \"wow\": 0, \"cares\": 5, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 66, \"comments\": 5, \"content\": \" FPT Software launches FCT Summer Camp 2023 The opening ceremony of FPT Software Computer Talents (FCT) Summer Camp 2023 was officially held at Hola Park campus, along with an awards ceremony honoring the outstanding students and instructors from the previous year. Initiated by our Chairwoman, FCT Club is open every year to students aged 12-16 who are enthusiastic about programming and computer science. With a variety of learning and team-building activities, the program is a great way for young students to gain valuable technology knowledge and develop soft skills that will benefit them in the future. ----- FPT Software kh\u1edfi \u0111\u1ed9ng tr\u1ea1i h\u00e8 FCT 2023 L\u1ec5 khai m\u1ea1c tr\u1ea1i h\u00e8 FPT Software Computer Talents (FCT) 2023 \u0111\u00e3 ch\u00ednh th\u1ee9c di\u1ec5n ra t\u1ea1i campus CodeCation Hola Park, c\u00f9ng v\u1edbi l\u1ec5 vinh danh nh\u1eefng h\u1ecdc vi\u00ean v\u00e0 gi\u1ea3ng vi\u00ean xu\u1ea5t s\u1eafc nh\u1ea5t c\u1ee7a n\u0103m tr\u01b0\u1edbc. \u0110\u01b0\u1ee3c kh\u1edfi x\u01b0\u1edbng b\u1edfi Ch\u1ee7 t\u1ecbch c\u1ee7a FPT Software, FCT Club m\u1edf c\u1eeda h\u00e0ng n\u0103m cho c\u00e1c h\u1ecdc sinh t\u1eeb 12-16 tu\u1ed5i \u0111am m\u00ea l\u1eadp tr\u00ecnh v\u00e0 khoa h\u1ecdc m\u00e1y t\u00ednh. V\u1edbi \u0111a d\u1ea1ng c\u00e1c ho\u1ea1t \u0111\u1ed9ng h\u1ecdc t\u1eadp v\u00e0 x\u00e2y d\u1ef1ng \u0111\u1ed9i nh\u00f3m, ch\u01b0\u01a1ng tr\u00ecnh l\u00e0 n\u01a1i b\u1ea1n tr\u1ebb c\u00f3 c\u01a1 h\u1ed9i v\u1eeba ph\u00e1t tri\u1ec3n c\u00e1c ki\u1ebfn th\u1ee9c v\u1ec1 c\u00f4ng ngh\u1ec7, v\u1eeba trau d\u1ed3i th\u00eam c\u00e1c k\u1ef9 n\u0103ng m\u1ec1m. \", \"posted_on\": \"2023-07-21T10:31:00\", \"video\": [], \"image\": [\"https://scontent.fhan3-2.fna.fbcdn.net/v/t39.30808-6/362254992_663055149182718_9221431248454415636_n.jpg?stp=dst-jpg_p526x395&_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=t7bwLyD6xdcAX9HaUxg&_nc_ht=scontent.fhan3-2.fna&oh=00_AfClEMyywWnYXbY7ty7uAgMGsTmnE83_pEHnF4ybzYSdcQ&oe=64CB0BC0\", \"https://scontent.fhan3-2.fna.fbcdn.net/v/t39.30808-6/362267094_663037495851150_6217160788668013042_n.jpg?stp=dst-jpg_p600x600&_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=9GJ_LMllBwgAX8FPg8b&_nc_ht=scontent.fhan3-2.fna&oh=00_AfC9aQKE6OpnaM95E9g9zh31UV4cAMYTLOOcutmjNhclmQ&oe=64CA8DFE\", \"https://scontent.fhan3-2.fna.fbcdn.net/v/t39.30808-6/362223419_663037505851149_3547108002077027995_n.jpg?stp=dst-jpg_p600x600&_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=E5n1mIXng94AX9i6GIM&_nc_ht=scontent.fhan3-2.fna&oh=00_AfAL0hGg0ZUd_zr2wzLYDO3LCIf_kQM4YMVSr3QcZz_b2g&oe=64CBA49F\", \"https://scontent.fhan3-4.fna.fbcdn.net/v/t39.30808-6/362248734_663037569184476_3974811230396852354_n.jpg?stp=dst-jpg_p600x600&_nc_cat=106&ccb=1-7&_nc_sid=730e14&_nc_ohc=HVXi1byVN5cAX_9PmUa&_nc_ht=scontent.fhan3-4.fna&oh=00_AfAixTgxjNMkEuBLzwjT-1jT08fSlCYM09G7-bWfY4hEpw&oe=64CAB6EE\", \"https://static.xx.fbcdn.net/rsrc.php/v3/y9/r/Z-dbClQDXLv.png\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0J5cxK3LCvDedaqQmXxU9tdSs7oijLZbQJK7BQ2CMBgvin2fc77Ytdp5Ymp5cah6jl?__cft__[0]=AZVIkPRhU03VpCm7becGwBld5GnlujJCRUTwSSPwA9rfC2MB1m6jC7ftavj5tE0QKSSaG33Qvwxd-Hy0BjT5IqwIR4bpCi19gD5feILITWK669-BE8k-CWJOGLLir-HvDQjSA4HLvyksc_nBPWJv6rJUFMoRZDfuDNABvr_LeetUmWYb7KoAywNemllDtHFtVb9VE6BWaYPDq6yxZ8v8MoH2&__tn__=%2CO%2CP-R\"}, \"pfbid0fEhtwTB1vGpA8fsGkXSz9F5mP1iwFCzZJVyZLKAgDzex3sWdGFrLX9s8fMFnAhAjl\": {\"name\": \"FPT Software\", \"shares\": 0, \"reactions\": {\"likes\": 11, \"loves\": 3, \"wow\": 0, \"cares\": 1, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 15, \"comments\": 0, \"content\": \" FPT Software Launches FezyFlow, A No-code Workflow PlatformWe are thrilled to announce the launch of FezyFlow, #FPTSoftware's innovative No-code Workflow Platform powered by AI. With FezyFlow, we aim to usher in a new era of technology that empowers enterprises in their digital transformation journey.----- FPT Software ra m\u1eaft FezyFlow, N\u1ec1n t\u1ea3ng \u1ee9ng d\u1ee5ng Low-code Ch\u00fang t\u00f4i r\u1ea5t vui m\u1eebng \u0111\u01b0\u1ee3c th\u00f4ng b\u00e1o v\u1ec1 vi\u1ec7c ra m\u1eaft n\u1ec1n t\u1ea3ng #FezyFlow, \u1ee9ng d\u1ee5ng c\u00f4ng ngh\u1ec7 Low-code gi\u00fap doanh nghi\u1ec7p qu\u1ea3n l\u00fd to\u00e0n di\u1ec7n quy tr\u00ecnh l\u00e0m vi\u1ec7c, qua \u0111\u00f3 ti\u1ebfp t\u1ee5c kh\u1eb3ng \u0111\u1ecbnh s\u1ef1 \u0111\u1ed3ng h\u00e0nh c\u1ee7a FPT Software v\u1edbi c\u00e1c \u0111\u1ed1i t\u00e1c to\u00e0n c\u1ea7u tr\u00ean h\u00e0nh tr\u00ecnh chuy\u1ec3n \u0111\u1ed5i s\u1ed1.\", \"posted_on\": \"2023-07-20T15:45:00\", \"video\": [\"blob:https://www.facebook.com/6e06d8a9-26e1-49c4-8143-f0181996fb55\"], \"image\": [\"https://scontent.fhan3-5.fna.fbcdn.net/v/t15.5256-10/361629916_6836088056415705_4837791711277401877_n.jpg?stp=dst-jpg_p180x540&_nc_cat=109&ccb=1-7&_nc_sid=ad6a45&_nc_ohc=XaBx9CMYSyYAX8VB_YP&_nc_ht=scontent.fhan3-5.fna&oh=00_AfCotBqh7dHGaffNF7xe65fQM0O_1oVcltycpWwBAhfupg&oe=64CA61C4\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0fEhtwTB1vGpA8fsGkXSz9F5mP1iwFCzZJVyZLKAgDzex3sWdGFrLX9s8fMFnAhAjl?__cft__[0]=AZUDWpZNTjb8XIGR771eJIHstc8qIplcG8BTyKmx_QBBqTcSEjDxWweZjpdggs53knizqLivliUfnqlF5MZpZnTWPOQPBke8Da1vDOVzwzHx9baFDPAjtCFW9A0joRhoCN4ji6tbWvgNZvUBgIAy2QN7ngdHUwtdS8gaMV5gPptb3MIt10H3v-CXqTNvg2qIeIgJ4MzWIPN0slv-Iq1d0mDT&__tn__=%2CO%2CP-R\"}, \"pfbid0kYncPwe91ZNmQGkedoTk9eaQnavNfzFX3QJjinDQgEwBaVRLB8KXZUJc6KY281owl\": {\"name\": \"FPT Software\", \"shares\": 3, \"reactions\": {\"likes\": 30, \"loves\": 7, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 37, \"comments\": 2, \"content\": \" Jacqueline and her impressions of FPT Software Coming from the Philippines, Jacqueline Cate Catley chose to work on-site in Vietnam to experience a diverse, professional, and exciting work environment where she could develop her expertise as an embedded software engineer. Check out Jacqueline's story on Episode 4 of Start with Me series!----- Jacqueline v\u00e0 nh\u1eefng \u1ea5n t\u01b0\u1ee3ng c\u1ee7a c\u00f4 v\u1ec1 FPT Software H\u00e0nh tr\u00ecnh c\u1ee7a Jacqueline Cate Catley t\u1eeb Philippines \u0111\u1ebfn Vi\u1ec7t Nam l\u00e0m vi\u1ec7c v\u1edbi mong mu\u1ed1n \u0111\u01b0\u1ee3c tr\u1ea3i nghi\u1ec7m m\u00f4i tr\u01b0\u1eddng \u0111a d\u1ea1ng, chuy\u00ean nghi\u1ec7p v\u00e0 th\u00fa v\u1ecb. \u0110\u00e2y c\u0169ng l\u00e0 c\u01a1 h\u1ed9i ph\u00f9 h\u1ee3p \u0111\u1ec3 ch\u1ecb ph\u00e1t tri\u1ec3n chuy\u00ean m\u00f4n trong v\u1ecb tr\u00ed Embedded Software Engineer. C\u00f9ng l\u1eafng nghe c\u00e2u chuy\u1ec7n c\u1ee7a Jacqueline trong t\u1eadp m\u1edbi nh\u1ea5t c\u1ee7a Start with Me!\", \"posted_on\": \"2023-07-20T09:30:00\", \"video\": [\"blob:https://www.facebook.com/4f8cfc81-e640-4228-bbe6-04244e80c9a6\"], \"image\": [], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0kYncPwe91ZNmQGkedoTk9eaQnavNfzFX3QJjinDQgEwBaVRLB8KXZUJc6KY281owl?__cft__[0]=AZWqwcx7IXqJoKqgx91yHA5SOoYjO-hhfR4xjSXuaBrYtwzVUI00jm8sbA8ehmLIZzvLJ7IrMEhg-W7JH1anz35UBq4FhFRQcrKej-qz_T4jgePvRmYVp5mhZIvSXeTbMD8YWEZzY2LQ-w9VqoDgUbOrJvUBlyvsDSeXnsmQqKdw0rFMOkf9LW3k4Gcn_XqNmStWWARZ23Jas6o09yJCugMH&__tn__=%2CO%2CP-R\"}, \"pfbid02KgzeaLNT5gqsFvA1xfZEsVE6nG6cH5xEKGcjeJtP1s63TmvtoPcCLJ2LMwfXYoxal\": {\"name\": \"FPT Software\", \"shares\": 1, \"reactions\": {\"likes\": 42, \"loves\": 6, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 48, \"comments\": 5, \"content\": \" FPT Software becomes a comprehensive software partner of Nippon Seiki GroupFPT Software recently inked a partnership agreement with Nippon Seiki \u2013 the world's leading supplier of information display products for automobiles and motorcycles with a 70-year history of operation. According to the agreement, FPT Software is responsible for the full life-cycle software development, while Nippon Seiki focuses on hardware development for global supply. During the signing ceremony, Chairwoman Chu Thi Thanh Ha shared, \\\"Becoming a partner with Nippon Seiki, we commit to exerting our best efforts to bring the best achievements for both parties. On the occasion of the 50th anniversary of the diplomatic relationship between Vietnam and Japan, the collaboration between FPT Software and Nippon Seiki hopes to contribute to the business and technology development of both countries.\\\"----- FPT Software tr\u1edf th\u00e0nh \u0111\u1ed1i t\u00e1c ph\u1ea7n m\u1ec1m to\u00e0n di\u1ec7n c\u1ee7a T\u1eadp \u0111o\u00e0n Nippon SeikiFPT Software v\u1eeba k\u00fd k\u1ebft h\u1ee3p t\u00e1c v\u1edbi Nippon Seiki \u2013 t\u1eadp \u0111o\u00e0n s\u1ea3n xu\u1ea5t ph\u1ee5 t\u00f9ng \u0111o t\u1ed1c \u0111\u1ed9 \u00f4t\u00f4, xe m\u00e1y h\u00e0ng \u0111\u1ea7u th\u1ebf gi\u1edbi v\u1edbi l\u1ecbch s\u1eed 70 n\u0103m ho\u1ea1t \u0111\u1ed9ng. Theo th\u1ecfa thu\u1eadn, FPT Software ch\u1ecbu tr\u00e1ch nhi\u1ec7m ph\u00e1t tri\u1ec3n to\u00e0n b\u1ed9 v\u00f2ng \u0111\u1eddi ph\u1ea7n m\u1ec1m, trong khi Nippon Seiki t\u1eadp trung v\u00e0o ph\u00e1t tri\u1ec3n ph\u1ea7n c\u1ee9ng \u0111\u1ec3 cung c\u1ea5p to\u00e0n c\u1ea7u. T\u1ea1i l\u1ec5 k\u00fd k\u1ebft, Ch\u1ee7 t\u1ecbch Chu Th\u1ecb Thanh H\u00e0 chia s\u1ebb: \u201cTr\u1edf th\u00e0nh \u0111\u1ed1i t\u00e1c v\u1edbi Nippon Seiki, ch\u00fang t\u00f4i cam k\u1ebft n\u1ed7 l\u1ef1c h\u1ebft m\u00ecnh \u0111\u1ec3 mang l\u1ea1i th\u00e0nh t\u1ef1u t\u1ed1t nh\u1ea5t cho c\u1ea3 hai b\u00ean. Nh\u00e2n k\u1ef7 ni\u1ec7m 50 n\u0103m m\u1ed1i quan h\u1ec7 quan h\u1ec7 ngo\u1ea1i giao hai n\u01b0\u1edbc Vi\u1ec7t Nam - Nh\u1eadt B\u1ea3n, h\u1ee3p t\u00e1c gi\u1eefa FPT Software v\u00e0 Nippon Seiki hy v\u1ecdng s\u1ebd g\u00f3p ph\u1ea7n th\u00fac \u0111\u1ea9y s\u1ef1 ph\u00e1t tri\u1ec3n kinh doanh v\u00e0 c\u00f4ng ngh\u1ec7 c\u1ee7a c\u1ea3 hai n\u01b0\u1edbc.\u201d\", \"posted_on\": \"2023-07-19T16:26:00\", \"video\": [], \"image\": [\"https://scontent.fhan3-2.fna.fbcdn.net/v/t39.30808-6/361670679_662050185949881_5887929389236935255_n.jpg?stp=dst-jpg_p526x395&_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=12NMHF7FcQgAX8keiwA&_nc_ht=scontent.fhan3-2.fna&oh=00_AfCTE2mEj7FnUrIo1nW8TvvGMP8B5t1AiXfHc95xA84qQA&oe=64CB52F5\", \"https://scontent.fhan4-2.fna.fbcdn.net/v/t39.30808-6/361672664_662050209283212_9142121149689910871_n.jpg?stp=dst-jpg_p600x600&_nc_cat=111&ccb=1-7&_nc_sid=730e14&_nc_ohc=GPEEFXg7aW8AX_0QJ80&_nc_ht=scontent.fhan4-2.fna&oh=00_AfBOxZ0HFYzAaR43lPetWRNOBZ3nNhWpp6tAziSDOBzBZA&oe=64CBD9A6\", \"https://scontent.fhan3-4.fna.fbcdn.net/v/t39.30808-6/361857675_662050249283208_3610987814087992444_n.jpg?stp=dst-jpg_p600x600&_nc_cat=104&ccb=1-7&_nc_sid=730e14&_nc_ohc=ARjqLXTmMpUAX--hwqg&_nc_oc=AQlzvAzSgGD5-HJT7wCNU4PQPMsI7j8YbmmfLtDrLsk5Qf0-hOJoSSrisSKCWtkmywGVwddrMKTRKOrLUcq8i0Yh&_nc_ht=scontent.fhan3-4.fna&oh=00_AfCqp9teO6inzv7K28tLofHrVObRLsnHoYnuK1afvXb8rg&oe=64CA6820\", \"https://scontent.fhan3-2.fna.fbcdn.net/v/t39.30808-6/361853135_662050262616540_9103295569799048320_n.jpg?stp=dst-jpg_p600x600&_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=n9R0gDVnUjkAX-jJ9aO&_nc_ht=scontent.fhan3-2.fna&oh=00_AfBf9ry5TeXoUHMFGLe_ijl8yxF1Ay9xomrFZ0zRh-KmyA&oe=64CA8F49\", \"https://static.xx.fbcdn.net/rsrc.php/v3/yw/r/8iuTX4LlGZO.png\", \"https://external.fhan3-5.fna.fbcdn.net/emg1/v/t13/9915410461051278487?url=https%3A%2F%2Fvcdn1-kinhdoanh.vnecdn.net%2F2023%2F07%2F19%2FImage-ExtractWord-2-Out-2645-1689757126.png%3Fw%3D1200%26h%3D0%26q%3D100%26dpr%3D1%26fit%3Dcrop%26s%3Dqb6Ujw3QP5ZtUrh3BHvqXw&fb_obo=1&utld=vnecdn.net&stp=c0.5000x0.5000f_dst-emg0_p98x98_q75&ccb=13-1&oh=06_AbHZ08qVf46IB--pQ0MA_sS540XGE35yT9U35Egr6ioKNQ&oe=64C820C6&_nc_sid=dbad39\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid02KgzeaLNT5gqsFvA1xfZEsVE6nG6cH5xEKGcjeJtP1s63TmvtoPcCLJ2LMwfXYoxal?__cft__[0]=AZW3xyzXYd11Lkj8ImcaLthkdpB_Abg49t9d7BvOvh0hNeSBHCPqcpHeUv7EP8idDkNa_obrcxqyDJd6hF2jfU-LaZv7g4Wb-PMixtjCp7VVPPp_-W2nj4pl1Kt-4JC3P4HFgWLGMxzZnlKdpNwT18AcGMs1c6q2OEZmn__Adv5AlVvT9HVeMKUUJuGoFNHBOfG6NVQU_sFrjMs2FQjvIZLO&__tn__=%2CO%2CP-R\"}, \"pfbid02yy8JB8jk4n3bXvUYSoGo3rLMKbUJbM9LZJwyNjjVx31eUg9HhLE6V9ThNkndoUC9l\": {\"name\": \"FPT Software\", \"shares\": 11, \"reactions\": {\"likes\": 97, \"loves\": 29, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 126, \"comments\": 8, \"content\": \"Get ready to be inspired by our talented and kind-hearted designer, Mr. Dang Thai Tuan Joining #FPTSoftware during his fourth year of university, equipped with just an iPad and boundless imagination, Tuan quickly becomes a standout designer due to his creative artworks. Among them, the painting \\\"H\u00e0 N\u1ed9i Rong\\\" was auctioned for 8,000 USD. He also donated half of this amount to the Project Carry Forward to support Vietnamese children affected by Covid-19. Tuan shares that FPT Software not only brings you opportunities to participate in unique technological projects but also creates an ideal working environment that fosters creativity. -----C\u00f9ng g\u1eb7p g\u1ee1 ch\u00e0ng designer t\u00e0i n\u0103ng v\u00e0 t\u1ed1t b\u1ee5ng c\u1ee7a FPT Software - \u0110\u1eb7ng Th\u00e1i Tu\u1ea5n Gia nh\u1eadp FPT Software t\u1eeb khi c\u00f2n l\u00e0 sinh vi\u00ean n\u0103m 4, ch\u1ec9 v\u1edbi chi\u1ebfc iPad v\u00e0 tr\u00ed t\u01b0\u1edfng t\u01b0\u1ee3ng \u201ckh\u00f4ng gi\u1edbi h\u1ea1n\u201d, Tu\u1ea5n s\u1edbm tr\u1edf th\u00e0nh m\u1ed9t designer t\u00e0i n\u0103ng b\u1edfi nh\u1eefng s\u1ea3n ph\u1ea9m s\u00e1ng t\u1ea1o. Trong \u0111\u00f3 b\u1ee9c \u201cHanoi Rong\u201d \u0111\u01b0\u1ee3c \u0111\u1ea5u gi\u00e1 8.000 USD. M\u1ed9t n\u1eeda s\u1ed1 ti\u1ec1n n\u00e0y c\u0169ng \u0111\u00e3 \u0111\u01b0\u1ee3c Tu\u1ea5n quy\u00ean g\u00f3p cho #ProjectCarryForward \u0111\u1ec3 h\u1ed7 tr\u1ee3 tr\u1ebb em Vi\u1ec7t Nam b\u1ecb \u1ea3nh h\u01b0\u1edfng b\u1edfi Covid-19.Tu\u1ea5n chia s\u1ebb FPT Software kh\u00f4ng ch\u1ec9 mang \u0111\u1ebfn cho b\u1ea1n c\u01a1 h\u1ed9i \u0111\u01b0\u1ee3c tham gia v\u00e0o nhi\u1ec1u d\u1ef1 \u00e1n c\u00f4ng ngh\u1ec7 \u0111\u1eb7c s\u1eafc m\u00e0 c\u00f2n l\u00e0 m\u1ed9t m\u00f4i tr\u01b0\u1eddng l\u00e0m vi\u1ec7c l\u00fd t\u01b0\u1edfng t\u1eeb \u0111\u00f3 k\u00edch th\u00edch s\u1ef1 s\u00e1ng t\u1ea1o trong b\u1ea1n. \", \"posted_on\": \"2023-07-19T10:58:00\", \"video\": [], \"image\": [\"https://scontent.fhan3-5.fna.fbcdn.net/v/t39.30808-6/361655976_661923545962545_2287383107573184854_n.jpg?stp=dst-jpg_p526x395&_nc_cat=110&ccb=1-7&_nc_sid=730e14&_nc_ohc=-v0bQgFGUnwAX-w1-N_&_nc_ht=scontent.fhan3-5.fna&oh=00_AfD1eR19IS1R0T40r_d0rQACNKBOzrL2UyF4V3-3yLT8YQ&oe=64CBDE59\", \"https://scontent.fhan4-1.fna.fbcdn.net/v/t39.30808-6/361845669_661923562629210_470033539903198143_n.jpg?stp=dst-jpg_p600x600&_nc_cat=105&ccb=1-7&_nc_sid=730e14&_nc_ohc=OgjTYK9y_cEAX9c2TyB&_nc_ht=scontent.fhan4-1.fna&oh=00_AfBFo56aYiNx8CsCFOFDcTwPny4LUS3XqZv1Sn9h2FlVUQ&oe=64CB4F65\", \"https://scontent.fhan3-4.fna.fbcdn.net/v/t39.30808-6/361855491_661923689295864_4217200555573597892_n.jpg?stp=dst-jpg_p600x600&_nc_cat=106&ccb=1-7&_nc_sid=730e14&_nc_ohc=6zIB07tcXHoAX8EpWVi&_nc_ht=scontent.fhan3-4.fna&oh=00_AfAsJJPXxiYh8zVMH50POUxe-P_Knk0olKmQRaEmy9JHww&oe=64CC2881\", \"https://scontent.fhan3-2.fna.fbcdn.net/v/t39.30808-6/361656401_661923715962528_8211779194616276371_n.jpg?stp=dst-jpg_p600x600&_nc_cat=107&ccb=1-7&_nc_sid=730e14&_nc_ohc=ld_7JPK-UKgAX8DTWCi&_nc_ht=scontent.fhan3-2.fna&oh=00_AfBOMWJi0VoWn5SR6hvTOGlEEv-sJ-p-Ksvufr8r_RlGKQ&oe=64CAAD8E\", \"https://static.xx.fbcdn.net/rsrc.php/v3/yw/r/8iuTX4LlGZO.png\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid02yy8JB8jk4n3bXvUYSoGo3rLMKbUJbM9LZJwyNjjVx31eUg9HhLE6V9ThNkndoUC9l?__cft__[0]=AZV0LBygFuu-X3qC16vly_coBEiL9QmFhHKuaso6_xJA-gDR6TgcayN4gev1AyUzozeX80gFfpzdbiBUIy3UxOPc1WwaZcE-FFdE0dKyq4hjyPvcvY3xORymbITSH9IcPXASaj3TSU8owakgzmGygtqSxUj3d7yEueqccuWBtjLxpXzw5QDmv-_FUoIcPGJCVgzdcVxVuhFF5sHwKdpmOq9Ot25Z3OWyUxVa4J4qasQe8w&__tn__=%2CO%2CP-R\"}, \"pfbid02XVddwdAVBv2XgJozsS8kzCW85FzXsz62VEDZf2YVCav7sUH1SAVBgw4Y7caZSgfgl\": {\"name\": \"FPT Software\", \"shares\": 9, \"reactions\": {\"likes\": 1600, \"loves\": 0, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 1600, \"comments\": 16, \"content\": \" FPT Software stands alongside the 'giant' Google This is the second consecutive year that #FPTSoftware has partnered with Google Developer Group to organize Google I/O Extended events for developers and technology enthusiasts. In addition to introducing the latest technologies from Google and Google's partners such as Bard AI, Flutter, Android, Firebase, and TensorFlow, this year's program also provides an opportunity for attendees to meet and connect with talented speakers and experts in the field of technology. Guest Speaker Khanh Nghiem, Solution Architect at FPT Software AI Center, will present a session titled \\\"AI-Powered Developer Tools,\\\" which promises to provide valuable knowledge to the software developer community about AI tools that support daily programming tasks. ----- FPT Software s\u00e1nh vai c\u00f9ng '\u00f4ng l\u1edbn' Google \u0110\u00e2y l\u00e0 n\u0103m th\u1ee9 hai li\u00ean ti\u1ebfp FPT Software \u0111\u1ed3ng h\u00e0nh c\u00f9ng Google Developer Group trong vi\u1ec7c t\u1ed5 ch\u1ee9c c\u00e1c s\u1ef1 ki\u1ec7n Google I/O Extended d\u00e0nh cho nh\u1eefng nh\u00e0 ph\u00e1t tri\u1ec3n v\u00e0 nh\u1eefng ng\u01b0\u1eddi \u0111am m\u00ea c\u00f4ng ngh\u1ec7. Ngo\u00e0i vi\u1ec7c gi\u1edbi thi\u1ec7u c\u00e1c c\u00f4ng ngh\u1ec7 m\u1edbi nh\u1ea5t t\u1eeb Google v\u00e0 c\u00e1c \u0111\u1ed1i t\u00e1c c\u1ee7a Google nh\u01b0 Bard AI, Flutter, Android, Firebase, TensorFlow, ch\u01b0\u01a1ng tr\u00ecnh n\u0103m nay c\u00f2n l\u00e0 d\u1ecbp \u0111\u1ec3 ng\u01b0\u1eddi tham d\u1ef1 c\u00f3 th\u1ec3 g\u1eb7p g\u1ee1 v\u00e0 k\u1ebft n\u1ed1i v\u1edbi c\u00e1c di\u1ec5n gi\u1ea3 t\u00e0i n\u0103ng, c\u00e1c chuy\u00ean gia trong l\u0129nh v\u1ef1c c\u00f4ng ngh\u1ec7. Di\u1ec5n gi\u1ea3 Kh\u00e1nh Nghi\u00eam, Solution Architect c\u1ee7a FPT Software AI Center s\u1ebd mang \u0111\u1ebfn s\u1ef1 ki\u1ec7n b\u00e0i chia s\u1ebb \u201cC\u00f4ng c\u1ee5 AI t\u1ed1i \u01b0u h\u00f3a l\u1eadp tr\u00ecnh\u201d (AI-Powered Developer Tools). B\u00e0i chia s\u1ebb n\u00e0y h\u1ee9a h\u1eb9n s\u1ebd cung c\u1ea5p nh\u1eefng ki\u1ebfn th\u1ee9c gi\u00e1 tr\u1ecb cho c\u1ed9ng \u0111\u1ed3ng software developer v\u1ec1 c\u00e1c c\u00f4ng c\u1ee5 AI h\u1ed7 tr\u1ee3 cho c\u00e1c t\u00e1c v\u1ee5 l\u1eadp tr\u00ecnh h\u00e0ng ng\u00e0y.\", \"posted_on\": \"2023-07-18T10:58:00\", \"video\": [], \"image\": [\"https://scontent.fhan3-5.fna.fbcdn.net/v/t39.30808-6/361632862_661337299354503_1178718634625653856_n.jpg?stp=dst-jpg_p526x296&_nc_cat=109&ccb=1-7&_nc_sid=730e14&_nc_ohc=KA1qJOp6yMAAX_2jGux&_nc_ht=scontent.fhan3-5.fna&oh=00_AfA-aHpzmMGJdSw0KufgnCnrXJJIGP4-WmyfsTBwPxA37g&oe=64CA6275\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid02XVddwdAVBv2XgJozsS8kzCW85FzXsz62VEDZf2YVCav7sUH1SAVBgw4Y7caZSgfgl?__cft__[0]=AZUT9oXOraP9jc4vLK1oVQQDSkj8_s7Xj5WpFB-w6YC8rkeN88O-0AdsEyGPQ4GwC8-6jBFQUYxFpH6VohgplS_FLFy_p-GtD4Pd37vN0GPUwDXiAE0Q39JRhp2pKm-Z2nqdDC5Djnt1UFzT33_GmcLdNKd_C1VlCE-9BbpebJrGOP0wUH-R3ykqrMkntkcuAKZuXPRZufDwrXOQLyyVNaVE&__tn__=%2CO%2CP-R\"}, \"pfbid024mBCGMC78H42qyCBiTWu5c5oiQFmkqBKFTXCt9KTY6zTkNwLbPsQ8owdf6dkSQWYl\": {\"name\": \"FPT Software\", \"shares\": 1, \"reactions\": {\"likes\": 19, \"loves\": 10, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 29, \"comments\": 1, \"content\": \" Chief AI Officer, Dr Nguyen Xuan Phong on Biztech\u2019s Technology ShowFPT Software Chief Artificial Intelligence Officer Dr. Phong Nguyen speaks with Biztech Asia about #AI developments and potential, and how the company is leveraging the technology for social goods.Tune in for more insights into FPT Software's strategic partnerships and groundbreaking projects that have fostered beneficial and responsible use of AI.-----Chief Artificial Intelligence Officer c\u1ee7a FPT Software, Ti\u1ebfn s\u0129 Phong Nguy\u1ec5n \u0111\u00e3 c\u00f3 cu\u1ed9c n\u00f3i chuy\u1ec7n v\u1edbi Biztech Asia v\u1ec1 nh\u1eefng ti\u1ec1m n\u0103ng c\u1ee7a Tr\u00ed tu\u1ec7 Nh\u00e2n t\u1ea1o (AI), v\u00e0 c\u00e1ch c\u00f4ng ty \u0111ang t\u1eadn d\u1ee5ng c\u00f4ng ngh\u1ec7 n\u00e0y cho nh\u1eefng m\u1ee5c ti\u00eau x\u00e3 h\u1ed9i.C\u00f9ng \u0111\u00f3n xem \u0111\u1ec3 t\u00ecm hi\u1ec3u v\u1ec1 c\u00e1c m\u1ed1i quan h\u1ec7 \u0111\u1ed1i t\u00e1c chi\u1ebfn l\u01b0\u1ee3c c\u1ee7a FPT Software v\u00e0 c\u00e1c d\u1ef1 \u00e1n \u0111\u1ed9t ph\u00e1 c\u1ee7a c\u00f4ng ty trong vi\u1ec7c th\u00fac \u0111\u1ea9y qu\u00e1 tr\u00ecnh s\u1eed d\u1ee5ng tr\u00ed tu\u1ec7 nh\u00e2n t\u1ea1o m\u1ed9t c\u00e1ch c\u00f3 \u00edch v\u00e0 c\u00f3 tr\u00e1ch nhi\u1ec7m.\", \"posted_on\": \"2023-07-17T11:11:00\", \"video\": [], \"image\": [\"https://external.fhan3-5.fna.fbcdn.net/emg1/v/t13/15271949908459455011?url=https%3A%2F%2Fi.ytimg.com%2Fvi%2FZYhfWSAR3t4%2Fmaxresdefault.jpg&fb_obo=1&utld=ytimg.com&stp=c0.5000x0.5000f_dst-jpg_flffffff_p500x261_q75&ccb=13-1&oh=06_AbFJb75k2_ERr7-Tmw9QLRC2ZZi83I73XaqGSdx3vPHFNA&oe=64C803E1&_nc_sid=dbad39\", \"https://static.xx.fbcdn.net/rsrc.php/v3/yw/r/8iuTX4LlGZO.png\", \"https://external.fhan3-5.fna.fbcdn.net/emg1/v/t13/4096199492705593923?url=https%3A%2F%2Fwww.biztech.asia%2Fwp-content%2Fuploads%2F2023%2F07%2FWebsite-Thumbnails-2-1.png&fb_obo=1&utld=biztech.asia&stp=c0.5000x0.5000f_dst-emg0_p98x98_q75&ccb=13-1&oh=06_AbHTlviIv1B62lhDYbY_v_sk28_fTLrbZigpFzIBWIipOw&oe=64C8008E&_nc_sid=dbad39\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid024mBCGMC78H42qyCBiTWu5c5oiQFmkqBKFTXCt9KTY6zTkNwLbPsQ8owdf6dkSQWYl?__cft__[0]=AZWh-Njq53rcE-oImRUO6oaU2qynZXFirPKw54s8bXHzKshrjnEB9gCWa5yjFKNgoqxXhs8H-p2uBWBlhjpEe-3ea4BjbAuFSPgNGmMUPzYtYJyKt7HFje809Bf5xFTq3bMNMFpxgqxaIyelz0w3DD4g5CWG-E--2KLGnEK2kpc-cUdZjX9zhk_qQMGNZipXcFz6VaW4gMsvsv5O1xnHiYG7&__tn__=%2CO%2CP-R\"}, \"pfbid0tNZ9x2ZiPAHKuPQnGxTJ4xSSYVDrCN4XiRYLHSFy6sVTeaGnNnefYaat4pgxARXPl\": {\"name\": \"FPT Software\", \"shares\": 4, \"reactions\": {\"likes\": 29, \"loves\": 2, \"wow\": 0, \"cares\": 0, \"sad\": 0, \"angry\": 0, \"haha\": 0}, \"reaction_count\": 31, \"comments\": 3, \"content\": \" FPT Software is honored to welcome Ambassador Hans-Peter Glanzer Mr Hans-Peter Glanzer, the Ambassador of the Republic of Austria to Vietnam, and Ms Le Thi Thanh Van, Head of Austrian Embassy Commercial section in Hanoi made a special visit to FPT University and #FPTSoftware campus in Hoa Lac.The Ambassador expressed his appreciation for FPT's efforts and outstanding results in working with major Austrian enterprises. He also recognized FPT's pivotal role in driving digital transformation and fostering growth for European partners, particularly in the automotive and energy sectors. Mr. Hans-Peter also pledged to facilitate smooth processes to ensure a seamless working experience for FPT engineers in Austria. Moreover, he expressed his commitment to connecting more businesses to foster collaborations with FPT. ----- FPT Software vinh d\u1ef1 \u0111\u01b0\u1ee3c \u0111\u00f3n ti\u1ebfp \u0110\u1ea1i s\u1ee9 Hans-Peter Glanzer Ng\u00e0i Hans-Peter Glanzer, \u0110\u1ea1i s\u1ee9 C\u1ed9ng h\u00f2a \u00c1o t\u1ea1i Vi\u1ec7t Nam v\u00e0 b\u00e0 L\u00ea Th\u1ecb Thanh V\u00e2n, Tr\u01b0\u1edfng ph\u00f2ng Th\u01b0\u01a1ng m\u1ea1i \u0110\u1ea1i s\u1ee9 qu\u00e1n \u00c1o t\u1ea1i H\u00e0 N\u1ed9i \u0111\u00e3 c\u00f3 chuy\u1ebfn th\u0103m \u0111\u1eb7c bi\u1ec7t t\u1edbi \u0110\u1ea1i h\u1ecdc FPT v\u00e0 FPT Software campus t\u1ea1i H\u00f2a L\u1ea1c.\u0110\u1ea1i s\u1ee9 \u0111\u00e1nh gi\u00e1 cao nh\u1eefng n\u1ed7 l\u1ef1c v\u00e0 k\u1ebft qu\u1ea3 n\u1ed5i b\u1eadt c\u1ee7a FPT trong qu\u00e1 tr\u00ecnh l\u00e0m vi\u1ec7c v\u1edbi c\u00e1c doanh nghi\u1ec7p l\u1edbn c\u1ee7a \u00c1o. \u00d4ng c\u0169ng ghi nh\u1eadn vai tr\u00f2 then ch\u1ed1t c\u1ee7a FPT trong vi\u1ec7c th\u00fac \u0111\u1ea9y chuy\u1ec3n \u0111\u1ed5i k\u1ef9 thu\u1eadt s\u1ed1 v\u00e0 th\u00fac \u0111\u1ea9y t\u0103ng tr\u01b0\u1edfng cho c\u00e1c \u0111\u1ed1i t\u00e1c ch\u00e2u \u00c2u, \u0111\u1eb7c bi\u1ec7t l\u00e0 trong l\u0129nh v\u1ef1c \u00f4 t\u00f4 v\u00e0 n\u0103ng l\u01b0\u1ee3ng. \u00d4ng Hans-Peter c\u0169ng cam k\u1ebft s\u1ebd t\u1ea1o \u0111i\u1ec1u ki\u1ec7n cho c\u00e1c c\u00e1n b\u1ed9, k\u1ef9 s\u01b0 FPT sang l\u00e0m vi\u1ec7c thu\u1eadn l\u1ee3i t\u1ea1i \u00c1o. Ngo\u00e0i ra, \u00f4ng c\u0169ng b\u00e0y t\u1ecf s\u1ebd n\u1ed7 l\u1ef1c trong vi\u1ec7c k\u1ebft n\u1ed1i nhi\u1ec1u doanh nghi\u1ec7p h\u01a1n n\u1eefa \u0111\u1ec3 th\u00fac \u0111\u1ea9y h\u1ee3p t\u00e1c v\u1edbi FPT.\", \"posted_on\": \"2023-07-14T14:37:00\", \"video\": [], \"image\": [\"https://scontent.fhan3-3.fna.fbcdn.net/v/t39.30808-6/361618772_660736266081273_2335379951210337994_n.jpg?stp=dst-jpg_p526x296&_nc_cat=108&ccb=1-7&_nc_sid=730e14&_nc_ohc=HiTmpQEQayoAX-nvUc_&_nc_ht=scontent.fhan3-3.fna&oh=00_AfBFzvPe86Fbfpcjxfkt91g398dms7h-RZjXmfW4C4gJwQ&oe=64CC11AA\", \"https://scontent.fhan3-5.fna.fbcdn.net/v/t39.30808-6/361555495_660736636081236_4051983395154751157_n.jpg?stp=dst-jpg_p600x600&_nc_cat=110&ccb=1-7&_nc_sid=730e14&_nc_ohc=L2IKqTQxnVEAX-NESfa&_nc_ht=scontent.fhan3-5.fna&oh=00_AfDj37FfC9L2jM5nj70f4Nj0GxDhcMiYtVbiMZtAYQfArA&oe=64CBFA3F\", \"https://scontent.fhan3-3.fna.fbcdn.net/v/t39.30808-6/361607197_660736619414571_4378496297738484511_n.jpg?stp=dst-jpg_p600x600&_nc_cat=101&ccb=1-7&_nc_sid=730e14&_nc_ohc=5xOUVFGjo8sAX-wV5qi&_nc_oc=AQlBY6hvjno8wTBEviRveqEqrwEfFZW5grMGfdSDbnR1upWOc4-xIfHvfKYY_jsoQPLny83rqMLkhSdjYxJq0aS8&_nc_ht=scontent.fhan3-3.fna&oh=00_AfB3JsJoDFUmINGnXWnaTrUgFszzsXfyPt3Q_sescIKyLQ&oe=64CBFB52\"], \"post_url\": \"https://www.facebook.com/fptsoftware.official/posts/pfbid0tNZ9x2ZiPAHKuPQnGxTJ4xSSYVDrCN4XiRYLHSFy6sVTeaGnNnefYaat4pgxARXPl?__cft__[0]=AZX-Xnju1izJlnyW8q_PaF9sV1cmL1eVr1N1X7nhvGHWqM43GXZ3SIQ1J17hm4C0KFPMeefgB1QtmxC5O0O6qyN1rbYvJeWFPVizDUkOeOf6NkoC0f9ZZn8kGWN9TQaXAgnm6SIcZhHA03TKQr4hOKQwtN9S1XcxjalRjd5CY0PADzZIgcXSvrjkeCrcxGpic6UoiugLo7k__qiEXw8pZCSN&__tn__=%2CO%2CP-R\"}}" \ No newline at end of file diff --git a/geckodriver.log b/geckodriver.log deleted file mode 100644 index 64661d489612942003869f637eb8c51985cee16c..0000000000000000000000000000000000000000 --- a/geckodriver.log +++ /dev/null @@ -1,1625 +0,0 @@ -1690368820273 geckodriver INFO Listening on 127.0.0.1:55067 -1690368823322 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "--marionette" "--headless" "--no-sandbox" "--disable-dev- ... 5068" "--remote-allow-hosts" "localhost" "-no-remote" "-profile" "C:\\Users\\PC\\AppData\\Local\\Temp\\rust_mozprofilefQjnTE" -*** You are running in headless mode. -console.warn: services.settings: Ignoring preference override of remote settings server -console.warn: services.settings: Allow by setting MOZ_REMOTE_SETTINGS_DEVTOOLS=1 in the environment -1690368823970 Marionette INFO Marionette enabled -Dynamically enable window occlusion 0 -console.error: "Warning: unrecognized command line flag -no-sandbox\n" -console.error: "Warning: unrecognized command line flag -ignore-certificate-errors\n" -console.error: "Warning: unrecognized command line flag -log-level\n" -console.error: "Warning: unrecognized command line flag -disable-notifications\n" -1690368824070 Marionette INFO Listening on port 55075 -WebDriver BiDi listening on ws://127.0.0.1:55068 -Read port: 55075 -1690368824286 RemoteAgent WARN TLS certificate errors will be ignored for this session -1690368824287 RemoteAgent INFO Proxy settings initialised: {"proxyType":"manual","httpProxy":"127.0.0.1:55066","sslProxy":"127.0.0.1:55066"} -[GFX1-]: RenderCompositorSWGL failed mapping default framebuffer, no dt -console.error: ({}) -DevTools listening on ws://127.0.0.1:55068/devtools/browser/67647121-8cd1-4bfb-9b8f-27121e5daab4 -1690368825793 Marionette WARN Ignoring event 'pageshow' because document has an invalid readyState of 'uninitialized'. -1690368873750 geckodriver INFO Listening on 127.0.0.1:55179 -1690368876801 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "--marionette" "--headless" "--no-sandbox" "--disable-dev- ... 5180" "--remote-allow-hosts" "localhost" "-no-remote" "-profile" "C:\\Users\\PC\\AppData\\Local\\Temp\\rust_mozprofile3xPNTn" -*** You are running in headless mode. -console.warn: services.settings: Ignoring preference override of remote settings server -console.warn: services.settings: Allow by setting MOZ_REMOTE_SETTINGS_DEVTOOLS=1 in the environment -1690368877304 Marionette INFO Marionette enabled -Dynamically enable window occlusion 0 -console.error: "Warning: unrecognized command line flag -no-sandbox\n" -console.error: "Warning: unrecognized command line flag -ignore-certificate-errors\n" -console.error: "Warning: unrecognized command line flag -log-level\n" -console.error: "Warning: unrecognized command line flag -disable-notifications\n" -1690368877375 Marionette INFO Listening on port 55190 -WebDriver BiDi listening on ws://127.0.0.1:55180 -Read port: 55190 -1690368877592 RemoteAgent WARN TLS certificate errors will be ignored for this session -1690368877594 RemoteAgent INFO Proxy settings initialised: {"proxyType":"manual","httpProxy":"127.0.0.1:55178","sslProxy":"127.0.0.1:55178"} -[GFX1-]: RenderCompositorSWGL failed mapping default framebuffer, no dt -console.error: ({}) -DevTools listening on ws://127.0.0.1:55180/devtools/browser/6ff71134-5fb3-4f10-8a1d-c43bb6ab6c82 -JavaScript warning: https://static.xx.fbcdn.net/rsrc.php/v3i01N4/yr/l/en_GB/yT-E7-pUlW5.js?_nc_x=Ij3Wp8lg5Kz, line 40: WEBGL_debug_renderer_info is deprecated in Firefox and will be removed. Please use RENDERER. -1690368938249 Marionette INFO Stopped listening on port 55190 -Dynamically enable window occlusion 1 -1690369072042 geckodriver INFO Listening on 127.0.0.1:55712 -1690369075093 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "--marionette" "--headless" "--no-sandbox" "--disable-dev- ... 5713" "--remote-allow-hosts" "localhost" "-no-remote" "-profile" "C:\\Users\\PC\\AppData\\Local\\Temp\\rust_mozprofilemYFSzF" -*** You are running in headless mode. -console.warn: services.settings: Ignoring preference override of remote settings server -console.warn: services.settings: Allow by setting MOZ_REMOTE_SETTINGS_DEVTOOLS=1 in the environment -1690369075711 Marionette INFO Marionette enabled -Dynamically enable window occlusion 0 -console.error: "Warning: unrecognized command line flag -no-sandbox\n" -console.error: "Warning: unrecognized command line flag -ignore-certificate-errors\n" -console.error: "Warning: unrecognized command line flag -log-level\n" -console.error: "Warning: unrecognized command line flag -disable-notifications\n" -1690369075808 Marionette INFO Listening on port 55721 -WebDriver BiDi listening on ws://127.0.0.1:55713 -Read port: 55721 -1690369076061 RemoteAgent WARN TLS certificate errors will be ignored for this session -1690369076062 RemoteAgent INFO Proxy settings initialised: {"proxyType":"manual","httpProxy":"127.0.0.1:55711","sslProxy":"127.0.0.1:55711"} -[GFX1-]: RenderCompositorSWGL failed mapping default framebuffer, no dt -console.error: ({}) -DevTools listening on ws://127.0.0.1:55713/devtools/browser/fb53cb23-e3c0-4daf-92ca-0775e3a1b88f -JavaScript warning: https://static.xx.fbcdn.net/rsrc.php/v3i01N4/yr/l/en_GB/yT-E7-pUlW5.js?_nc_x=Ij3Wp8lg5Kz, line 40: WEBGL_debug_renderer_info is deprecated in Firefox and will be removed. Please use RENDERER. -1690369153113 Marionette INFO Stopped listening on port 55721 -Dynamically enable window occlusion 1 -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -console.error: RemoteSecuritySettings.jsm: - Failed to download attachment: TypeError: NetworkError: Network request failed -JavaScript error: https://static.xx.fbcdn.net/rsrc.php/v3iKMN4/yb/l/en_GB/OSId1g6zVUE.js?_nc_x=Ij3Wp8lg5Kz, line 300: TypeError: can't access dead object -JavaScript error: https://static.xx.fbcdn.net/rsrc.php/v3iKMN4/yb/l/en_GB/OSId1g6zVUE.js?_nc_x=Ij3Wp8lg5Kz, line 300: TypeError: can't access dead object -JavaScript error: https://static.xx.fbcdn.net/rsrc.php/v3iKMN4/yb/l/en_GB/OSId1g6zVUE.js?_nc_x=Ij3Wp8lg5Kz, line 300: TypeError: can't access dead object -JavaScript error: https://static.xx.fbcdn.net/rsrc.php/v3iKMN4/yb/l/en_GB/OSId1g6zVUE.js?_nc_x=Ij3Wp8lg5Kz, line 300: TypeError: can't access dead object -JavaScript error: https://static.xx.fbcdn.net/rsrc.php/v3iKMN4/yb/l/en_GB/OSId1g6zVUE.js?_nc_x=Ij3Wp8lg5Kz, line 300: TypeError: can't access dead object diff --git a/history/binh/2023-08-06_17-10-17/Assistance Inquiry.json b/history/binh/2023-08-06_17-10-17/Assistance Inquiry.json new file mode 100644 index 0000000000000000000000000000000000000000..d4b581c102e1681b8e1d31ceeaa3eebe44e6ca77 --- /dev/null +++ b/history/binh/2023-08-06_17-10-17/Assistance Inquiry.json @@ -0,0 +1 @@ +{"history": [["Hello bot", "Hello! How can I assist you today?"]], "chatbot": [["Hello bot", "Hello! How can I assist you today?"]]} \ No newline at end of file diff --git a/html_parser.py b/html_parser.py deleted file mode 100644 index 02e431bfe00f3347d10d5d63f4e035995217fdcb..0000000000000000000000000000000000000000 --- a/html_parser.py +++ /dev/null @@ -1,116 +0,0 @@ -"""HTML parser. - -Contains parser for html files. - -""" -import re -from pathlib import Path -from typing import Dict, Union -from abc import abstractmethod -from pathlib import Path -from typing import Dict, List, Optional, Union - - -class BaseParser: - """Base class for all parsers.""" - - def __init__(self, parser_config: Optional[Dict] = None): - """Init params.""" - self._parser_config = parser_config - - def init_parser(self) -> None: - """Init parser and store it.""" - parser_config = self._init_parser() - self._parser_config = parser_config - - @property - def parser_config_set(self) -> bool: - """Check if parser config is set.""" - return self._parser_config is not None - - @property - def parser_config(self) -> Dict: - """Check if parser config is set.""" - if self._parser_config is None: - raise ValueError("Parser config not set.") - return self._parser_config - - @abstractmethod - def _init_parser(self) -> Dict: - """Initialize the parser with the config.""" - - @abstractmethod - def parse_file(self, file: Path, errors: str = "ignore") -> Union[str, List[str]]: - """Parse file.""" - -class HTMLParser(BaseParser): - """HTML parser.""" - - def _init_parser(self) -> Dict: - """Init parser.""" - return {} - - def parse_file(self, file: Path, errors: str = "ignore") -> Union[str, list[str]]: - """Parse file. - - Returns: - Union[str, List[str]]: a string or a List of strings. - """ - try: - from unstructured.partition.html import partition_html - from unstructured.staging.base import convert_to_isd - from unstructured.cleaners.core import clean - except ImportError: - raise ValueError("unstructured package is required to parse HTML files.") - - # Using the unstructured library to convert the html to isd format - # isd sample : isd = [ - # {"text": "My Title", "type": "Title"}, - # {"text": "My Narrative", "type": "NarrativeText"} - # ] - with open(file, "r", encoding="utf-8") as fp: - elements = partition_html(file=fp) - isd = convert_to_isd(elements) - - # Removing non ascii charactwers from isd_el['text'] - for isd_el in isd: - isd_el['text'] = isd_el['text'].encode("ascii", "ignore").decode() - - # Removing all the \n characters from isd_el['text'] using regex and replace with single space - # Removing all the extra spaces from isd_el['text'] using regex and replace with single space - for isd_el in isd: - isd_el['text'] = re.sub(r'\n', ' ', isd_el['text'], flags=re.MULTILINE | re.DOTALL) - isd_el['text'] = re.sub(r"\s{2,}", " ", isd_el['text'], flags=re.MULTILINE | re.DOTALL) - - # more cleaning: extra_whitespaces, dashes, bullets, trailing_punctuation - for isd_el in isd: - clean(isd_el['text'], extra_whitespace=True, dashes=True, bullets=True, trailing_punctuation=True) - - # Creating a list of all the indexes of isd_el['type'] = 'Title' - title_indexes = [i for i, isd_el in enumerate(isd) if isd_el['type'] == 'Title'] - - # Creating 'Chunks' - List of lists of strings - # each list starting with with isd_el['type'] = 'Title' and all the data till the next 'Title' - # Each Chunk can be thought of as an individual set of data, which can be sent to the model - # Where Each Title is grouped together with the data under it - - Chunks = [[]] - final_chunks = list(list()) - - for i, isd_el in enumerate(isd): - if i in title_indexes: - Chunks.append([]) - Chunks[-1].append(isd_el['text']) - - # Removing all the chunks with sum of lenth of all the strings in the chunk < 25 - # TODO: This value can be an user defined variable - for chunk in Chunks: - # sum of lenth of all the strings in the chunk - sum = 0 - sum += len(str(chunk)) - if sum < 25: - Chunks.remove(chunk) - else: - # appending all the approved chunks to final_chunks as a single string - final_chunks.append(" ".join([str(item) for item in chunk])) - return final_chunks diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e90edce7f5cebfff70ea2d7a5baa935be404c571 Binary files /dev/null and b/logo.png differ diff --git a/process_fb.py b/process_fb.py deleted file mode 100644 index bdb26b15107b9767b3f2d9528f4e3d329daec71e..0000000000000000000000000000000000000000 --- a/process_fb.py +++ /dev/null @@ -1,55 +0,0 @@ -import json -import ast -import os -import pinecone - -from pydantic import Field -from vector_db import Document -from html_parser import HTMLParser -from langchain.vectorstores import Pinecone -from config import PINECONE_API_KEY, PINECONE_ENVIRONMENT, INDEX_NAME -from config import EMBEDDING_API_BASE, EMBEDDING_API_KEY, OPENAI_API_TYPE, OPENAI_API_VERSION, EMBEDDING_DEPLOYMENT_ID -from langchain.embeddings import OpenAIEmbeddings - - -# initialize pinecone -pinecone.init( - api_key=PINECONE_API_KEY, # find at app.pinecone.io - environment=PINECONE_ENVIRONMENT, # next to api key in console -) - -# Azure embedding model definition -embeddings = OpenAIEmbeddings( - deployment=EMBEDDING_DEPLOYMENT_ID, - openai_api_key=EMBEDDING_API_KEY, - openai_api_base=EMBEDDING_API_BASE, - openai_api_type=OPENAI_API_TYPE, - openai_api_version=OPENAI_API_VERSION, - chunk_size=16 -) - -if INDEX_NAME and INDEX_NAME not in pinecone.list_indexes(): - pinecone.create_index( - INDEX_NAME, - metric="cosine", - dimension=1536 - ) - print(f"Index {INDEX_NAME} created successfully") - -index = pinecone.Index(INDEX_NAME) - -with open('data.json') as json_file: - data = json.load(json_file) -datas = ast.literal_eval(data) - -texts = [] -for k, v in datas.items(): - content = v["content"] - post_url = v["post_url"] - texts.append(Document(page_content=content, metadata={"source": post_url})) - -if len(texts)>0: - Pinecone.from_documents(texts, embeddings, index_name=INDEX_NAME) - message = f"Add files to {INDEX_NAME} sucessfully" - print(message) - diff --git a/process_html.py b/process_html.py deleted file mode 100644 index b023f345278a17cc8479d20acaf234ba85b471f9..0000000000000000000000000000000000000000 --- a/process_html.py +++ /dev/null @@ -1,58 +0,0 @@ - - -import os -import pinecone - -from pydantic import Field -from vector_db import Document -from html_parser import HTMLParser -from langchain.vectorstores import Pinecone -from config import PINECONE_API_KEY, PINECONE_ENVIRONMENT, INDEX_NAME -from config import EMBEDDING_API_BASE, EMBEDDING_API_KEY, OPENAI_API_TYPE, OPENAI_API_VERSION, EMBEDDING_DEPLOYMENT_ID -from langchain.embeddings import OpenAIEmbeddings - -WEBSITE_FOLDER = 'website' -parser = HTMLParser() - -# initialize pinecone -pinecone.init( - api_key=PINECONE_API_KEY, # find at app.pinecone.io - environment=PINECONE_ENVIRONMENT, # next to api key in console -) - -# Azure embedding model definition -embeddings = OpenAIEmbeddings( - deployment=EMBEDDING_DEPLOYMENT_ID, - openai_api_key=EMBEDDING_API_KEY, - openai_api_base=EMBEDDING_API_BASE, - openai_api_type=OPENAI_API_TYPE, - openai_api_version=OPENAI_API_VERSION, - chunk_size=16 -) - -if INDEX_NAME and INDEX_NAME not in pinecone.list_indexes(): - pinecone.create_index( - INDEX_NAME, - metric="cosine", - dimension=1536 - ) - print(f"Index {INDEX_NAME} created successfully") - -index = pinecone.Index(INDEX_NAME) -index.delete(delete_all=True) - -files_src = os.listdir(WEBSITE_FOLDER) -documents = [] -for file in files_src: - filepath = os.path.join(WEBSITE_FOLDER, file) - filename = os.path.basename(filepath) - data = parser.parse_file(filepath) - texts= [] - for d in data: - texts.append(Document(page_content=d, metadata={"source": filepath})) - documents.extend(texts) -print(len(documents)) -if len(documents)>0: - document_id = [d.metadata['document_id'] + f"_{idx}" for (idx, d) in enumerate(documents)] - Pinecone.from_documents(documents, embeddings, ids=document_id, index_name=INDEX_NAME) - message = f"Add website to {INDEX_NAME} sucessfully" \ No newline at end of file diff --git a/prompts/__pycache__/condense_llm.cpython-39.pyc b/prompts/__pycache__/condense_llm.cpython-39.pyc index 602d819d91ed1ed2ae1450e8c3f0846c196f635c..5dce75e7ee7ab8bb304e4e623fd113a560214e8b 100644 Binary files a/prompts/__pycache__/condense_llm.cpython-39.pyc and b/prompts/__pycache__/condense_llm.cpython-39.pyc differ diff --git a/prompts/__pycache__/create_topic.cpython-39.pyc b/prompts/__pycache__/create_topic.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16e56c3a32801a05b9b890a3cc42bd7bae89aaa3 Binary files /dev/null and b/prompts/__pycache__/create_topic.cpython-39.pyc differ diff --git a/prompts/__pycache__/custom_chain.cpython-39.pyc b/prompts/__pycache__/custom_chain.cpython-39.pyc index 401d2a646b5155bd17b9bd6f1d3b9b33d2d160d4..4a12d941af1eb4270d44e753402fe6234f036b99 100644 Binary files a/prompts/__pycache__/custom_chain.cpython-39.pyc and b/prompts/__pycache__/custom_chain.cpython-39.pyc differ diff --git a/prompts/__pycache__/decision_maker.cpython-39.pyc b/prompts/__pycache__/decision_maker.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b79304719f59146abfaba0ecc422869eed3d2ddc Binary files /dev/null and b/prompts/__pycache__/decision_maker.cpython-39.pyc differ diff --git a/prompts/__pycache__/llm.cpython-39.pyc b/prompts/__pycache__/llm.cpython-39.pyc index 1c4f37650c8a88957b5b6435a836cd3b33857437..6570a01596aa0669e71e6c9ada9491f7e71cd001 100644 Binary files a/prompts/__pycache__/llm.cpython-39.pyc and b/prompts/__pycache__/llm.cpython-39.pyc differ diff --git a/prompts/__pycache__/multi_queries.cpython-39.pyc b/prompts/__pycache__/multi_queries.cpython-39.pyc deleted file mode 100644 index f6782f872b18ffc8af956a8dfb71f23e3e891d54..0000000000000000000000000000000000000000 Binary files a/prompts/__pycache__/multi_queries.cpython-39.pyc and /dev/null differ diff --git a/prompts/__pycache__/related_question.cpython-39.pyc b/prompts/__pycache__/related_question.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6a0e462395866213bc5a51fd426074ddb175ccd Binary files /dev/null and b/prompts/__pycache__/related_question.cpython-39.pyc differ diff --git a/prompts/__pycache__/simple_chain.cpython-39.pyc b/prompts/__pycache__/simple_chain.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..acea860097a09920d21b96470f0f0a6886788ef1 Binary files /dev/null and b/prompts/__pycache__/simple_chain.cpython-39.pyc differ diff --git a/prompts/__pycache__/stage_analyzer.cpython-39.pyc b/prompts/__pycache__/stage_analyzer.cpython-39.pyc deleted file mode 100644 index eadb22633f66426982e8a192495d2522ca737de4..0000000000000000000000000000000000000000 Binary files a/prompts/__pycache__/stage_analyzer.cpython-39.pyc and /dev/null differ diff --git a/prompts/__pycache__/summary.cpython-39.pyc b/prompts/__pycache__/summary.cpython-39.pyc index 85f62cdf4cbf5d470e475797bd34dc12e0310fd5..2e5219d637bd97cdc5aaa4a77c1fcd539617b9ca 100644 Binary files a/prompts/__pycache__/summary.cpython-39.pyc and b/prompts/__pycache__/summary.cpython-39.pyc differ diff --git a/prompts/__pycache__/web_search.cpython-39.pyc b/prompts/__pycache__/web_search.cpython-39.pyc index 217f853f7f582c25b57da668c64cc8c296bb4157..24ef230e52acb4a0d8609ab29750ebca027f7747 100644 Binary files a/prompts/__pycache__/web_search.cpython-39.pyc and b/prompts/__pycache__/web_search.cpython-39.pyc differ diff --git a/prompts/condense_llm.py b/prompts/condense_llm.py index 351c7dfed0baec291895c0a4f0abac4ceed302db..faaf53480103ce4dcf1c822cf59f3df92a6e9dd9 100644 --- a/prompts/condense_llm.py +++ b/prompts/condense_llm.py @@ -1,5 +1,7 @@ -condense_template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, in its original language. -Chat History: +condense_template = """Below is a history of the conversation so far, and a new question asked by the user that needs to be answered by searching in a knowledge base. +Generate a search query based on the conversation and the new question. +If the question is not in English, answer in the language used in the question. +Conversation history: {chat_history} -Follow Up Input: {question} -Standalone question:""" \ No newline at end of file +New question: {question} +Search query:""" \ No newline at end of file diff --git a/prompts/create_topic.py b/prompts/create_topic.py new file mode 100644 index 0000000000000000000000000000000000000000..fa7c4ac71b80835aafdbde0c7a346eacad870964 --- /dev/null +++ b/prompts/create_topic.py @@ -0,0 +1,8 @@ +SYSTEM_PROMPT_TEMPLATE = "You are an AI assistant created by FPT Software to be helpful, harmless and honest." +HUMAN_PROMPT_TEMPLATE = """Please create a concise topic (less than 5 words) best suited for the following conversation. +Conversation: +\nHuman: {inputs}\nAssistant: {outputs} +Do not include any text inside \"\". +Do not include any special characters like '+'. +Do not generate any text before or after the topic, such as 'Topic:'. +""" \ No newline at end of file diff --git a/prompts/decision_maker.py b/prompts/decision_maker.py new file mode 100644 index 0000000000000000000000000000000000000000..116916cc6653defbade9210341f2cf2cf3e7a83c --- /dev/null +++ b/prompts/decision_maker.py @@ -0,0 +1,12 @@ +SYSTEM_PROMPT_TEMPLATE = \ +"""\ +You are an AI assistant created by FPT Software to be helpful, harmless and honest. +""" +HUMAN_PROMPT_TEMPLATE = \ +"""\ +Based on the user query, decide on what source to use. Your possible sources are given below: +1. LLM Model: Useful for answering conversational queries and for queries that you can fully answer +with just the knowledge from your database. +2. Google Web Search: Useful when the query is related to time-sensitive information, recent developments, or needs current data. +Please answer only the source used as "LLM Model" or "Google Web Search" and nothing else. +User query: {question}""" \ No newline at end of file diff --git a/prompts/llm.py b/prompts/llm.py index 8536026214eb5f5935f71ad02b82eb11be12c2c5..7c51bca32bb7c52b837b9df1ce8b828e8241ad69 100644 --- a/prompts/llm.py +++ b/prompts/llm.py @@ -1,4 +1,4 @@ -qa_prompt_template = """You are a DocsFPT, a friendly and helpful AI assistant that helps people find information. +qa_prompt_template = """You are an AI assistant created by FPT Software to be helpful, harmless and honest. Search result: --------------------- {context} @@ -6,12 +6,13 @@ Search result: Instructions: Compose a comprehensive reply to the query using the search results given. If the search result does not relate to the query or no search result is provided, simply state 'I don't have the information for this question, please provide me with more relevant documents so I can help you'. Do not use prior knowledge about FPT to answer the question. -Make sure to cite results using [number] notation (every result has this number at the beginning) after the reference. +if there are search result, make sure to cite results using [number] notation after the reference. Citation should be done at the end of each sentence. If the search results mention multiple subjects with the same name, create separate answers for each. +Please add the image URL (if any) in this conversation with the syntax: ![x](image_URL). Only include information found in the search result and don't add any additional information. Make sure the answer is correct and don't output false content. Ignore outlier search results that have nothing to do with the question. -Answer user queries in its original language with a friendly tone. +If the query is not in English, answer in the language used in the question with a friendly tone. Answer step-by-step. Conversation history: diff --git a/prompts/multi_queries.py b/prompts/multi_queries.py index 45f535e1d81024856066a51ac0b25c4480116592..e56a6972e6ff2e9091a1e541a51ca1b34379c846 100644 --- a/prompts/multi_queries.py +++ b/prompts/multi_queries.py @@ -1,4 +1,4 @@ system_template = "You are an AI helpful assistant" -human_template = """Translate the following original question into English and Malaysian. +human_template = """Translate the following original question into English. original question:{question}""" \ No newline at end of file diff --git a/prompts/related_question.py b/prompts/related_question.py new file mode 100644 index 0000000000000000000000000000000000000000..dd7b39a043d8501fe948c11d40578f45d0d1ed9c --- /dev/null +++ b/prompts/related_question.py @@ -0,0 +1,17 @@ +system_template = "You are an AI helpful assistant." +human_template = \ +"""\ +Create three very brief follow-up questions (below 6 words) that the user is likely to ask next based on the previous conversation. +Try not to repeat questions that have already been asked. +Only generate questions and do not generate any text before or after the questions. +The answer contains three questions formatted in Markdown. +Expected output: +- question 1 +- question 2 +- question 3 +where question 1, question 2, question 3 are the follow-up questions you ask. + +Conversation: +Human: {inputs} +AI: {outputs} +""" diff --git a/prompts/simple_chain.py b/prompts/simple_chain.py new file mode 100644 index 0000000000000000000000000000000000000000..2d302dc142d4a37910dc759bde356cedcd271f94 --- /dev/null +++ b/prompts/simple_chain.py @@ -0,0 +1,2 @@ +SYSTEM_PROMPT_TEMPLATE = "You are an AI assistant created by FPT Software to be helpful, harmless and honest." +HUMAN_PROMPT_TEMPLATE = "{question}" \ No newline at end of file diff --git a/prompts/stage_analyzer.py b/prompts/stage_analyzer.py deleted file mode 100644 index fb87c54a1e7b0d74760a4d95a10c53c6a62b8398..0000000000000000000000000000000000000000 --- a/prompts/stage_analyzer.py +++ /dev/null @@ -1,39 +0,0 @@ -#-------------------------- stage analyzer chain --------------------------------- -SYSTEM_MESSAGE_PROMPT = \ -""" -##Role -You are a sales assistant helping your sales agent to determine which stage of a sales conversation should the agent move to, or stay at. - -##Instructions -- Analyze the given context and conversation history -- Determine what should be the next instant chat stage for the agent in the sales chat by choosing one from the following options: - 1. Introduction: Start the conversation by introducing yourself and your company. Be polite and respectful while keeping the tone of the conversation professional. - 2. Qualification: Qualify the prospect by confirming if they are the right person to talk to regarding your product/service. Ensure that they have the authority to make purchasing decisions. - 3. Value proposition: Briefly explain how your product/service can benefit the prospect. Focus on the unique selling points and value proposition of your product/service that sets it apart from competitors. - 4. Needs analysis: Ask open-ended questions to uncover the prospect's needs and pain points. Listen carefully to their responses and take notes. - 5. Solution presentation: Based on the prospect's needs, present your product/service as the solution that can address their pain points. - 6. Objection handling: Address any objections that the prospect may have regarding your product/service. Be prepared to provide evidence or testimonials to support your claims. - 7. Close: Ask for the sale by proposing a next step. This could be a demo, a trial or a meeting with decision-makers. Ensure to summarize what has been discussed and reiterate the benefits. -- Only answer with a number between 1 through 7 with a best guess of what stage should the conversation continue with. - -##Rules -- If there is no conversation history, output 1. -- The answer needs to be one number only, no words. -- Do not answer anything else nor add anything to you answer.""" - -HUMAN_MESSAGE_PROMPT = \ -"""\ -Conversation history: -{chat_history} -As a/an Role, you must execute Instructions and follow provided Rules. -AI answer:""" - -conversation_stages = { - "1": "Introduction: Start the conversation by introducing yourself and your company. Be polite and respectful while keeping the tone of the conversation professional. Your greeting should be welcoming. Always clarify in your greeting the reason why you are contacting the prospect.", - "2": "Qualification: Qualify the prospect by confirming if they are the right person to talk to regarding your product/service. Ensure that they have the authority to make purchasing decisions.", - "3": "Value proposition: Briefly explain how your product/service can benefit the prospect. Focus on the unique selling points and value proposition of your product/service that sets it apart from competitors.", - "4": "Needs analysis: Ask open-ended questions to uncover the prospect's needs and pain points. Listen carefully to their responses and take notes.", - "5": "Solution presentation: Based on the prospect's needs, present your product/service as the solution that can address their pain points.", - "6": "Objection handling: Address any objections that the prospect may have regarding your product/service. Be prepared to provide evidence or testimonials to support your claims.", - "7": "Close: Ask for the sale by proposing a next step. This could be a demo, a trial or a meeting with decision-makers. Ensure to summarize what has been discussed and reiterate the benefits.", -} \ No newline at end of file diff --git a/prompts/web_search.py b/prompts/web_search.py index fba6f172a00bb527ca98be1ee78c5914450539fc..80994558a9605b73ceee20f987c2ef15d6bf50cc 100644 --- a/prompts/web_search.py +++ b/prompts/web_search.py @@ -1,4 +1,4 @@ -SYSTEM_PROMPT_TEMPLATE = "You are a DocsFPT, a friendly and helpful AI assistant that helps people find information.." +SYSTEM_PROMPT_TEMPLATE = "You are an AI assistant created by FPT Software to be helpful, harmless and honest." HUMAN_PROMPT_TEMPLATE = \ """\ Web search result: @@ -6,9 +6,10 @@ Web search result: {context} --------------------- Instructions: Using the provided web search results, write a comprehensive reply to the given query. -Make sure to cite results using [[number](URL)] notation after the reference +Make sure to cite results using [number] notation after the reference. Citation should be done at the end of each sentence. If the provided search results refer to multiple subjects with the same name, write separate answers for each subject. +If the user question is not in English, answer in the language used in the question. Answer in a friendly tone. Answer step-by-step. diff --git a/requirements.txt b/requirements.txt index 37de7418161e8ac64b1d3a37cc9ba5d5b5a29b2c..40b262daeb4dd241b1c15b2cf75eb6683f486f0b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ -langchain==0.0.200 +langchain==0.0.240 openai PyPDF2 -gradio==3.33.1 -gradio_client==0.2.7 +gradio==3.37.0 +gradio_client==0.3.0 tiktoken pinecone-client google-api-python-client bs4 -facebook-page-scraper +azure-storage-blob diff --git a/scrab_fb.py b/scrab_fb.py index efc5b65031e5fd4af789d53f27a298e69dfd3b45..467ff42cf1fd93521238ca70faa68928f6a83e8d 100644 --- a/scrab_fb.py +++ b/scrab_fb.py @@ -1,16 +1,63 @@ -import json -from facebook_page_scraper import Facebook_scraper -from facebook_page_scraper import Facebook_scraper +# import json +# from facebook_page_scraper import Facebook_scraper +# from facebook_page_scraper import Facebook_scraper +# from config import * +# #instantiate the Facebook_scraper class +# page_name = "fptsoftware.official" +# posts_count = 15 +# browser = "firefox" -#instantiate the Facebook_scraper class -page_name = "majlisbandaraya.pulaupinang" -posts_count = 30 -browser = "firefox" +# timeout = 600 #600 seconds +# headless = True +# meta_ai = Facebook_scraper(page_name, posts_count, browser, timeout=timeout, headless=headless) +# json_data = meta_ai.scrap_to_json() -timeout = 600 #600 seconds -headless = True -meta_ai = Facebook_scraper(page_name, posts_count, browser, timeout=timeout, headless=headless) -json_data = meta_ai.scrap_to_json() +# with open('data.json', 'w') as f: +# json.dump(json_data, f) +import json +from pydantic import Field +from langchain.load.serializable import Serializable +import pinecone +# from langchain.vectorstores import Pinecone +from custom_vectordb import Pinecone +from config import PINECONE_API_KEY, PINECONE_ENVIRONMENT, INDEX_NAME, CONNECTION_STRING, CONTAINER_NAME, NAME_SPACE_1, NAME_SPACE_2 +from config import EMBEDDING_API_BASE, EMBEDDING_API_KEY, OPENAI_API_TYPE, OPENAI_API_VERSION, EMBEDDING_DEPLOYMENT_ID +from langchain.embeddings import OpenAIEmbeddings +import ast +with open('data.json') as json_file: + data = json.load(json_file) +class Document(Serializable): + """Class for storing a piece of text and associated metadata.""" -with open('data.json', 'w') as f: - json.dump(json_data, f) \ No newline at end of file + page_content: str + """String text.""" + metadata: dict = Field(default_factory=dict) + """Arbitrary metadata about the page content (e.g., source, relationships to other + documents, etc.). + """ +datas = ast.literal_eval(data) +# initialize pinecone +pinecone.init( + api_key=PINECONE_API_KEY, # find at app.pinecone.io + environment=PINECONE_ENVIRONMENT, # next to api key in console +) +index = pinecone.Index(INDEX_NAME) +index.delete(delete_all=True, namespace=NAME_SPACE_2) +embeddings = OpenAIEmbeddings( + deployment=EMBEDDING_DEPLOYMENT_ID, + openai_api_key=EMBEDDING_API_KEY, + openai_api_base=EMBEDDING_API_BASE, + openai_api_type=OPENAI_API_TYPE, + openai_api_version=OPENAI_API_VERSION, + chunk_size=16 +) +texts = [] +for k, v in datas.items(): + content = v["content"].split("-----")[0] + "\nimage_link: " + str(v["image"]) + post_url = v["post_url"] + texts.append(Document(page_content=content, metadata={"source": post_url})) +print(len(texts)) +if len(texts)>0: + Pinecone.from_documents(texts, embeddings, index_name=INDEX_NAME, namespace=NAME_SPACE_2) + message = f"Add facebook data to space {NAME_SPACE_2} in {INDEX_NAME} sucessfully" + print(message) \ No newline at end of file diff --git a/test.html b/test.html new file mode 100644 index 0000000000000000000000000000000000000000..67fbbc404a57fef771b67060e27ecfc26d74a258 --- /dev/null +++ b/test.html @@ -0,0 +1,6 @@ +
+ +
\ No newline at end of file diff --git a/test.py b/test.py index 14f42e8eb90b8b316b7d1e4a90d2b8ed5dc119b2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/test.py +++ b/test.py @@ -1,66 +0,0 @@ -import pinecone -import os -import PyPDF2 -import shutil -import gradio as gr - -from tqdm import tqdm -from pydantic import Field -from typing import List, Optional -from langchain.load.serializable import Serializable - -from langchain.vectorstores import Pinecone -from config import PINECONE_API_KEY, PINECONE_ENVIRONMENT, INDEX_NAME, SAVE_DIR -from config import OPENAI_API_BASE, OPENAI_API_KEY, OPENAI_API_TYPE, OPENAI_API_VERSION, EMBEDDING_DEPLOYMENT_ID -from langchain.embeddings import OpenAIEmbeddings -from langchain.text_splitter import TokenTextSplitter - -class Document(Serializable): - """Class for storing a piece of text and associated metadata.""" - - page_content: str - """String text.""" - metadata: dict = Field(default_factory=dict) - """Arbitrary metadata about the page content (e.g., source, relationships to other - documents, etc.). - """ - -filepath = "documents\STANDARD_SOFTWARE LIFECYCLES.pdf" -pdftext = "" -text_splitter = TokenTextSplitter(chunk_size=500, chunk_overlap=30) -doc_chunks = [] -documents = [] -with open(filepath, "rb") as pdfFileObj: - pdf_reader = PyPDF2.PdfReader(pdfFileObj) - for page in tqdm(pdf_reader.pages): - pdftext += page.extract_text() - texts = [Document(page_content=pdftext, metadata={"source": filepath})] - texts = text_splitter.split_documents(texts) - documents.extend(texts) -print(documents[:3]) -# for (idx, docs) in enumerate(documents): -# docs.page_content = f"[{idx}] " + docs.page_content -def add_source_numbers(lst, source_name = "Source", use_source = True): - if use_source: - return [f'[{idx+1}]\t "{item[0]}"\n{source_name}: {item[1]}' for idx, item in enumerate(lst)] - else: - return [f'[{idx+1}]\t "{item}"' for idx, item in enumerate(lst)] - -for (idx, d) in enumerate(documents): - item = [d.page_content.strip("�"), os.path.basename(d.metadata["source"])] - d.page_content = f'[{idx+1}]\t "{item[0]}"\nSource: {item[1]}' -# print(reference_results) -# print("----------------") -# print(documents[:3]) - -def add_details(lst): - nodes = [] - for txt in lst: - brief = txt[:25].replace("\n", "") - nodes.append( - f"
{brief}...

{txt}

" - ) - return nodes -reference_results = [d.page_content for d in documents[:3]] -display_append = add_details(reference_results) -print(display_append) \ No newline at end of file diff --git a/theme_dropdown.py b/theme_dropdown.py new file mode 100644 index 0000000000000000000000000000000000000000..94d011b45fea90ab2f69230e9b01e0fb1bf6aac6 --- /dev/null +++ b/theme_dropdown.py @@ -0,0 +1,57 @@ +import os +import pathlib + +from gradio.themes.utils import ThemeAsset + + +def create_theme_dropdown(): + import gradio as gr + + asset_path = pathlib.Path(__file__).parent / "themes" + themes = [] + for theme_asset in os.listdir(str(asset_path)): + themes.append( + (ThemeAsset(theme_asset), gr.Theme.load(str(asset_path / theme_asset))) + ) + + def make_else_if(theme_asset): + return f""" + else if (theme == '{str(theme_asset[0].version)}') {{ + var theme_css = `{theme_asset[1]._get_theme_css()}` + }}""" + + head, tail = themes[0], themes[1:] + if_statement = f""" + if (theme == "{str(head[0].version)}") {{ + var theme_css = `{head[1]._get_theme_css()}` + }} {" ".join(make_else_if(t) for t in tail)} + """ + + latest_to_oldest = sorted([t[0] for t in themes], key=lambda asset: asset.version)[ + ::-1 + ] + latest_to_oldest = [str(t.version) for t in latest_to_oldest] + + component = gr.Dropdown( + choices=latest_to_oldest, + value=latest_to_oldest[0], + render=False, + label="Select Version", + ).style(container=False) + + return ( + component, + f""" + (theme) => {{ + if (!document.querySelector('.theme-css')) {{ + var theme_elem = document.createElement('style'); + theme_elem.classList.add('theme-css'); + document.head.appendChild(theme_elem); + }} else {{ + var theme_elem = document.querySelector('.theme-css'); + }} + {if_statement} + theme_elem.innerHTML = theme_css; + }} + """ + ) diff --git a/themes/theme_schema@0.0.3.json b/themes/theme_schema@0.0.3.json new file mode 100644 index 0000000000000000000000000000000000000000..c1b52bef8ee95be84e092e732e26ff52d5f49543 --- /dev/null +++ b/themes/theme_schema@0.0.3.json @@ -0,0 +1,324 @@ +{ + "theme": { + "_font": [ + { + "__gradio_font__": true, + "name": "Source Sans Pro", + "class": "google" + }, + { + "__gradio_font__": true, + "name": "ui-sans-serif", + "class": "font" + }, + { + "__gradio_font__": true, + "name": "system-ui", + "class": "font" + }, + { + "__gradio_font__": true, + "name": "sans-serif", + "class": "font" + } + ], + "_font_mono": [ + { + "__gradio_font__": true, + "name": "IBM Plex Mono", + "class": "google" + }, + { + "__gradio_font__": true, + "name": "ui-monospace", + "class": "font" + }, + { + "__gradio_font__": true, + "name": "Consolas", + "class": "font" + }, + { + "__gradio_font__": true, + "name": "monospace", + "class": "font" + } + ], + "_stylesheets": [ + "https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap", + "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&display=swap" + ], + "background_fill_primary": "white", + "background_fill_primary_dark": "*neutral_950", + "background_fill_secondary": "*neutral_50", + "background_fill_secondary_dark": "*neutral_900", + "block_background_fill": "*background_fill_primary", + "block_background_fill_dark": "*neutral_800", + "block_border_color": "*border_color_primary", + "block_border_color_dark": "*border_color_primary", + "block_border_width": "1px", + "block_info_text_color": "*body_text_color_subdued", + "block_info_text_color_dark": "*body_text_color_subdued", + "block_info_text_size": "*text_sm", + "block_info_text_weight": "400", + "block_label_background_fill": "*background_fill_primary", + "block_label_background_fill_dark": "*background_fill_secondary", + "block_label_border_color": "*border_color_primary", + "block_label_border_color_dark": "*border_color_primary", + "block_label_border_width": "1px", + "block_label_margin": "0", + "block_label_padding": "*spacing_sm *spacing_lg", + "block_label_radius": "calc(*radius_lg - 1px) 0 calc(*radius_lg - 1px) 0", + "block_label_right_radius": "0 calc(*radius_lg - 1px) 0 calc(*radius_lg - 1px)", + "block_label_text_color": "*neutral_500", + "block_label_text_color_dark": "*neutral_200", + "block_label_text_size": "*text_sm", + "block_label_text_weight": "400", + "block_padding": "*spacing_xl calc(*spacing_xl + 2px)", + "block_radius": "*radius_lg", + "block_shadow": "none", + "block_title_background_fill": "none", + "block_title_border_color": "none", + "block_title_border_width": "0px", + "block_title_padding": "0", + "block_title_radius": "none", + "block_title_text_color": "*neutral_500", + "block_title_text_color_dark": "*neutral_200", + "block_title_text_size": "*text_md", + "block_title_text_weight": "400", + "body_background_fill": "*background_fill_primary", + "body_background_fill_dark": "*background_fill_primary", + "body_text_color": "*neutral_800", + "body_text_color_dark": "*neutral_100", + "body_text_color_subdued": "*neutral_400", + "body_text_color_subdued_dark": "*neutral_400", + "body_text_size": "*text_md", + "body_text_weight": "400", + "border_color_accent": "*primary_300", + "border_color_accent_dark": "*neutral_600", + "border_color_primary": "*neutral_200", + "border_color_primary_dark": "*neutral_700", + "button_border_width": "*input_border_width", + "button_border_width_dark": "*input_border_width", + "button_cancel_background_fill": "*button_secondary_background_fill", + "button_cancel_background_fill_dark": "*button_secondary_background_fill", + "button_cancel_background_fill_hover": "*button_cancel_background_fill", + "button_cancel_background_fill_hover_dark": "*button_cancel_background_fill", + "button_cancel_border_color": "*button_secondary_border_color", + "button_cancel_border_color_dark": "*button_secondary_border_color", + "button_cancel_border_color_hover": "*button_cancel_border_color", + "button_cancel_border_color_hover_dark": "*button_cancel_border_color", + "button_cancel_text_color": "*button_secondary_text_color", + "button_cancel_text_color_dark": "*button_secondary_text_color", + "button_cancel_text_color_hover": "*button_cancel_text_color", + "button_cancel_text_color_hover_dark": "*button_cancel_text_color", + "button_large_padding": "*spacing_lg calc(2 * *spacing_lg)", + "button_large_radius": "*radius_lg", + "button_large_text_size": "*text_lg", + "button_large_text_weight": "600", + "button_primary_background_fill": "*primary_200", + "button_primary_background_fill_dark": "*primary_700", + "button_primary_background_fill_hover": "*button_primary_background_fill", + "button_primary_background_fill_hover_dark": "*button_primary_background_fill", + "button_primary_border_color": "*primary_200", + "button_primary_border_color_dark": "*primary_600", + "button_primary_border_color_hover": "*button_primary_border_color", + "button_primary_border_color_hover_dark": "*button_primary_border_color", + "button_primary_text_color": "*primary_600", + "button_primary_text_color_dark": "white", + "button_primary_text_color_hover": "*button_primary_text_color", + "button_primary_text_color_hover_dark": "*button_primary_text_color", + "button_secondary_background_fill": "*neutral_200", + "button_secondary_background_fill_dark": "*neutral_600", + "button_secondary_background_fill_hover": "*button_secondary_background_fill", + "button_secondary_background_fill_hover_dark": "*button_secondary_background_fill", + "button_secondary_border_color": "*neutral_200", + "button_secondary_border_color_dark": "*neutral_600", + "button_secondary_border_color_hover": "*button_secondary_border_color", + "button_secondary_border_color_hover_dark": "*button_secondary_border_color", + "button_secondary_text_color": "*neutral_700", + "button_secondary_text_color_dark": "white", + "button_secondary_text_color_hover": "*button_secondary_text_color", + "button_secondary_text_color_hover_dark": "*button_secondary_text_color", + "button_shadow": "none", + "button_shadow_active": "none", + "button_shadow_hover": "none", + "button_small_padding": "*spacing_sm calc(2 * *spacing_sm)", + "button_small_radius": "*radius_lg", + "button_small_text_size": "*text_md", + "button_small_text_weight": "400", + "button_transition": "background-color 0.2s ease", + "checkbox_background_color": "*background_fill_primary", + "checkbox_background_color_dark": "*neutral_800", + "checkbox_background_color_focus": "*checkbox_background_color", + "checkbox_background_color_focus_dark": "*checkbox_background_color", + "checkbox_background_color_hover": "*checkbox_background_color", + "checkbox_background_color_hover_dark": "*checkbox_background_color", + "checkbox_background_color_selected": "*secondary_600", + "checkbox_background_color_selected_dark": "*secondary_600", + "checkbox_border_color": "*neutral_300", + "checkbox_border_color_dark": "*neutral_700", + "checkbox_border_color_focus": "*secondary_500", + "checkbox_border_color_focus_dark": "*secondary_500", + "checkbox_border_color_hover": "*neutral_300", + "checkbox_border_color_hover_dark": "*neutral_600", + "checkbox_border_color_selected": "*secondary_600", + "checkbox_border_color_selected_dark": "*secondary_600", + "checkbox_border_radius": "*radius_sm", + "checkbox_border_width": "*input_border_width", + "checkbox_border_width_dark": "*input_border_width", + "checkbox_check": "url(\"data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e\")", + "checkbox_label_background_fill": "*button_secondary_background_fill", + "checkbox_label_background_fill_dark": "*button_secondary_background_fill", + "checkbox_label_background_fill_hover": "*button_secondary_background_fill_hover", + "checkbox_label_background_fill_hover_dark": "*button_secondary_background_fill_hover", + "checkbox_label_background_fill_selected": "*checkbox_label_background_fill", + "checkbox_label_background_fill_selected_dark": "*checkbox_label_background_fill", + "checkbox_label_border_color": "*border_color_primary", + "checkbox_label_border_color_dark": "*border_color_primary", + "checkbox_label_border_color_hover": "*checkbox_label_border_color", + "checkbox_label_border_color_hover_dark": "*checkbox_label_border_color", + "checkbox_label_border_width": "*input_border_width", + "checkbox_label_border_width_dark": "*input_border_width", + "checkbox_label_gap": "*spacing_lg", + "checkbox_label_padding": "*spacing_md calc(2 * *spacing_md)", + "checkbox_label_shadow": "none", + "checkbox_label_text_color": "*body_text_color", + "checkbox_label_text_color_dark": "*body_text_color", + "checkbox_label_text_color_selected": "*checkbox_label_text_color", + "checkbox_label_text_color_selected_dark": "*checkbox_label_text_color", + "checkbox_label_text_size": "*text_md", + "checkbox_label_text_weight": "400", + "checkbox_shadow": "*input_shadow", + "color_accent": "*primary_500", + "color_accent_soft": "*primary_50", + "color_accent_soft_dark": "*neutral_700", + "container_radius": "*radius_lg", + "embed_radius": "*radius_lg", + "error_background_fill": "#fee2e2", + "error_background_fill_dark": "*background_fill_primary", + "error_border_color": "#fecaca", + "error_border_color_dark": "*border_color_primary", + "error_border_width": "1px", + "error_text_color": "#ef4444", + "error_text_color_dark": "#ef4444", + "font": "'Source Sans Pro', 'ui-sans-serif', 'system-ui', sans-serif", + "font_mono": "'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace", + "form_gap_width": "0px", + "input_background_fill": "*neutral_100", + "input_background_fill_dark": "*neutral_700", + "input_background_fill_focus": "*secondary_500", + "input_background_fill_focus_dark": "*secondary_600", + "input_background_fill_hover": "*input_background_fill", + "input_background_fill_hover_dark": "*input_background_fill", + "input_border_color": "*border_color_primary", + "input_border_color_dark": "*border_color_primary", + "input_border_color_focus": "*secondary_300", + "input_border_color_focus_dark": "*neutral_700", + "input_border_color_hover": "*input_border_color", + "input_border_color_hover_dark": "*input_border_color", + "input_border_width": "0px", + "input_padding": "*spacing_xl", + "input_placeholder_color": "*neutral_400", + "input_placeholder_color_dark": "*neutral_500", + "input_radius": "*radius_lg", + "input_shadow": "none", + "input_shadow_focus": "*input_shadow", + "input_text_size": "*text_md", + "input_text_weight": "400", + "layout_gap": "*spacing_xxl", + "link_text_color": "*secondary_600", + "link_text_color_active": "*secondary_600", + "link_text_color_active_dark": "*secondary_500", + "link_text_color_dark": "*secondary_500", + "link_text_color_hover": "*secondary_700", + "link_text_color_hover_dark": "*secondary_400", + "link_text_color_visited": "*secondary_500", + "link_text_color_visited_dark": "*secondary_600", + "loader_color": "*color_accent", + "name": "base", + "neutral_100": "#f3f4f6", + "neutral_200": "#e5e7eb", + "neutral_300": "#d1d5db", + "neutral_400": "#9ca3af", + "neutral_50": "#f9fafb", + "neutral_500": "#6b7280", + "neutral_600": "#4b5563", + "neutral_700": "#374151", + "neutral_800": "#1f2937", + "neutral_900": "#111827", + "neutral_950": "#0b0f19", + "panel_background_fill": "*background_fill_secondary", + "panel_background_fill_dark": "*background_fill_secondary", + "panel_border_color": "*border_color_primary", + "panel_border_color_dark": "*border_color_primary", + "panel_border_width": "0", + "primary_100": "#dbeafe", + "primary_200": "#bfdbfe", + "primary_300": "#93c5fd", + "primary_400": "#60a5fa", + "primary_50": "#eff6ff", + "primary_500": "#3b82f6", + "primary_600": "#2563eb", + "primary_700": "#1d4ed8", + "primary_800": "#1e40af", + "primary_900": "#1e3a8a", + "primary_950": "#1d3660", + "prose_header_text_weight": "600", + "prose_text_size": "*text_md", + "prose_text_weight": "400", + "radio_circle": "url(\"data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e\")", + "radius_lg": "8px", + "radius_md": "6px", + "radius_sm": "4px", + "radius_xl": "12px", + "radius_xs": "2px", + "radius_xxl": "22px", + "radius_xxs": "1px", + "secondary_100": "#dbeafe", + "secondary_200": "#bfdbfe", + "secondary_300": "#93c5fd", + "secondary_400": "#60a5fa", + "secondary_50": "#eff6ff", + "secondary_500": "#3b82f6", + "secondary_600": "#2563eb", + "secondary_700": "#1d4ed8", + "secondary_800": "#1e40af", + "secondary_900": "#1e3a8a", + "secondary_950": "#1d3660", + "section_header_text_size": "*text_md", + "section_header_text_weight": "400", + "shadow_drop": "rgba(0,0,0,0.05) 0px 1px 2px 0px", + "shadow_drop_lg": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", + "shadow_inset": "rgba(0,0,0,0.05) 0px 2px 4px 0px inset", + "shadow_spread": "3px", + "shadow_spread_dark": "1px", + "slider_color": "auto", + "spacing_lg": "8px", + "spacing_md": "6px", + "spacing_sm": "4px", + "spacing_xl": "10px", + "spacing_xs": "2px", + "spacing_xxl": "16px", + "spacing_xxs": "1px", + "stat_background_fill": "*primary_300", + "stat_background_fill_dark": "*primary_500", + "table_border_color": "*neutral_300", + "table_border_color_dark": "*neutral_700", + "table_even_background_fill": "white", + "table_even_background_fill_dark": "*neutral_950", + "table_odd_background_fill": "*neutral_50", + "table_odd_background_fill_dark": "*neutral_900", + "table_radius": "*radius_lg", + "table_row_focus": "*color_accent_soft", + "table_row_focus_dark": "*color_accent_soft", + "text_lg": "16px", + "text_md": "14px", + "text_sm": "12px", + "text_xl": "22px", + "text_xs": "10px", + "text_xxl": "26px", + "text_xxs": "9px" + }, + "version": "0.0.1" +} \ No newline at end of file diff --git a/utils.py b/utils.py index c20aaf934c3ad3ffa46c673491fc60e56075329f..ca7946fc3ea9551291bd34244fefe29dd23a38cc 100644 --- a/utils.py +++ b/utils.py @@ -1,41 +1,89 @@ import datetime import os +import json +import gradio as gr from prompts.llm import qa_prompt_template from prompts.condense_llm import condense_template -from typing import Dict, Any from config import HISTORY_DIR -def get_messages_last_content(data: Dict[str, Any], **_: Any) -> str: - """ get the last content of the llm request messages array - :param data: the user llm request data - :type data: Dict[str, Any] - - Example: - .. code-block:: python - - from gptcache.processor.pre import get_messages_last_content - - content = get_messages_last_content({"messages": [{"content": "hello"}, {"content": "world"}]}) - # "world" - """ - result = data.get("messages")[-1].content.split("Human:")[-1].split("Assistant:")[0].strip() - print(result) - return result +def web_citation(inputs, results, custom_websearch=False): + import requests + + from bs4 import BeautifulSoup + from chains.summary import WebSummary + reference_results = [] + display_append = [] + for idx, result in enumerate(results): + try: + head = requests.head(result['link']) + if "text/html" in head.headers['Content-Type']: + html_response = requests.get(result['link']) + soup = BeautifulSoup(html_response.content, "html.parser") + if not custom_websearch: + title = result["title"] + else: + title = soup.find_all('title')[0].get_text() + try: + web_summary = WebSummary() + text = soup.get_text() + lines = (line.strip() for line in text.splitlines()) + # break multi-headlines into a line each + chunks = (phrase.strip() for line in lines for phrase in line.split(" ")) + # drop blank lines + text = '\n'.join(chunk for chunk in chunks if chunk) + + summary = web_summary.predict(question=inputs, doc=text) + print("Can access", result['link']) + reference_results.append([summary, result['link']]) + display_append.append( + f'{idx + 1}. {title}' + ) + except: + print("Cannot access ", result['link']) + except: + continue + return reference_results, display_append + + +def get_auth(): + if os.path.exists("auth.json"): + auth_list = [] + with open("auth.json", "r", encoding='utf-8') as f: + auth = json.load(f) + # print(auth) + for _ in auth: + if auth[_]["username"] and auth[_]["password"]: + auth_list.append((auth[_]["username"], auth[_]["password"])) + return auth_list def transcribe(current_model, audio): return current_model.audio_response(audio) -def history_file_path(username): - dirname = os.path.join(HISTORY_DIR, username) - os.makedirs(dirname, exist_ok=True) +def related_question(current_model): + return current_model.related_question() + + +def history_file_path(username, file_name): now = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') - history_path = os.path.join(dirname, f"{now}.json") + dirname = os.path.join(HISTORY_DIR, username, now) + os.makedirs(dirname, exist_ok=True) + history_path = os.path.join(dirname, f"{file_name}.json") return history_path +def get_history_names(plain=False, user_name=""): + from cosmos_db import query_item + items = query_item(user_name) + files = [item["id"] for item in items] + if plain: + return files + else: + return gr.update(choices=files) + + def load_lasted_file_username(username): if username not in os.listdir(HISTORY_DIR): return None @@ -48,36 +96,41 @@ def load_lasted_file_username(username): return os.path.join(HISTORY_DIR, username, lasted_file) -def load_chat_history(current_model, *args): - return current_model.load_history(*args) +def load_chat_history(current_model, file_name): + return current_model.load_history(file_name) +def save_chat_history(current_model, chatbot, file_name): + return current_model.save_history(chatbot, file_name) -def predict(chatbot, model, inputs, use_websearch, custom_websearch): - iter = model.inference(inputs=inputs, chatbot=chatbot, streaming=True, use_websearch=use_websearch, - custom_websearch=custom_websearch, qa_prompt_template=qa_prompt_template, - condense_prompt_template=condense_template) +def predict(chatbot, model, inputs, upload_files_btn, custom_websearch, local_db): + iter = model.inference(inputs=inputs, chatbot=chatbot, streaming=True, upload_files_btn=upload_files_btn, + custom_websearch=custom_websearch, qa_prompt_template=qa_prompt_template, + local_db=local_db, condense_prompt_template=condense_template) for response in iter: yield response -def set_user_indentifier(current_model, *args): - return current_model.set_user_indentifier(*args) +def set_user_identifier(current_model, *args): + return current_model.set_user_identifie(*args) -def retry(chatbot, model, use_websearch, custom_websearch): +def retry(chatbot, model, upload_files_btn, custom_websearch, local_db): model.delete_last_conversation() if len(chatbot) > 0: inputs = chatbot[-1][0] - chatbot = predict(chatbot, model, inputs, use_websearch, custom_websearch) - yield chatbot + iter = model.inference(inputs=inputs, chatbot=chatbot, streaming=True, upload_files_btn=upload_files_btn, + custom_websearch=custom_websearch, qa_prompt_template=qa_prompt_template, + local_db=local_db, condense_prompt_template=condense_template) + for response in iter: + yield response def reset(current_model): return current_model.reset_conversation() -def delete_chat_history(current_model, *args): - return current_model.delete_history(*args) +def delete_chat_history(current_model, file_name): + return current_model.delete_history(file_name) def delete_first_conversation(current_model): @@ -91,17 +144,17 @@ def delete_last_conversation(current_model, chatbot): return chatbot -def add_source_numbers(lst, source_name = "Source", use_source = True): +def add_source_numbers(lst, source_name="Source", use_source=True): if use_source: - return [f'[{idx+1}]\t "{item[0]}"\n{source_name}: {item[1]}' for idx, item in enumerate(lst)] + return [f'[{idx + 1}]\t "{item[0]}"\n{source_name}: {item[1]}' for idx, item in enumerate(lst)] else: - return [f'[{idx+1}]\t "{item}"' for idx, item in enumerate(lst)] + return [f'[{idx + 1}]\t "{item}"' for idx, item in enumerate(lst)] + -def add_details(lst): +def add_details(lst, lst_src): nodes = [] - for txt in lst: - brief = txt[:25].replace("\n", "") + for idx, (txt, src) in enumerate(zip(lst, lst_src)): nodes.append( - f"
{brief}...

{txt}

" + f"
{txt[:4]}{src}

{txt[4:]}

" ) - return nodes \ No newline at end of file + return nodes diff --git a/vector_db.py b/vector_db.py index d6dfeb72d86768727dbd401b807e41af60ccf686..7aa03227051e3e557d51949194c02048fc2561cc 100644 --- a/vector_db.py +++ b/vector_db.py @@ -1,21 +1,19 @@ import pinecone import os -import json -import ast import PyPDF2 -import shutil import gradio as gr from tqdm import tqdm from pydantic import Field -from typing import List, Optional from langchain.load.serializable import Serializable -from langchain.vectorstores import Pinecone -from config import PINECONE_API_KEY, PINECONE_ENVIRONMENT, INDEX_NAME, SAVE_DIR +# from langchain.vectorstores import Pinecone +from custom_vectordb import Pinecone +from config import PINECONE_API_KEY, PINECONE_ENVIRONMENT, INDEX_NAME, CONNECTION_STRING, CONTAINER_NAME, NAME_SPACE_1, NAME_SPACE_2 from config import EMBEDDING_API_BASE, EMBEDDING_API_KEY, OPENAI_API_TYPE, OPENAI_API_VERSION, EMBEDDING_DEPLOYMENT_ID from langchain.embeddings import OpenAIEmbeddings from langchain.text_splitter import TokenTextSplitter +from azure.storage.blob import BlobServiceClient # initialize pinecone pinecone.init( @@ -42,6 +40,8 @@ if INDEX_NAME and INDEX_NAME not in pinecone.list_indexes(): ) print(f"Index {INDEX_NAME} created successfully") index = pinecone.Index(INDEX_NAME) +blob_service_client = BlobServiceClient.from_connection_string(CONNECTION_STRING) + class Document(Serializable): """Class for storing a piece of text and associated metadata.""" @@ -53,70 +53,102 @@ class Document(Serializable): documents, etc.). """ - +# def update_fb(): +# with open('data.json') as json_file: +# data = json.load(json_file) +# datas = ast.literal_eval(data) + +# texts = [] +# for k, v in datas.items(): +# content = v["content"].split("-----")[0] + "\nimage_link: " + str(v["image"]) +# post_url = v["post_url"] +# texts.append(Document(page_content=content, metadata={"source": post_url})) + +# if len(texts)>0: +# Pinecone.from_documents(texts, embeddings, index_name=INDEX_NAME, namespace=NAME_SPACE_2) +# message = f"Add facebook data to space {NAME_SPACE_2} in {INDEX_NAME} sucessfully" +# return message + + +def upload_files_blob(file_path): + file_name = os.path.basename(file_path) + blob_client = blob_service_client.get_blob_client(container=CONTAINER_NAME, blob=file_name) + with open(file_path,'rb') as data: + blob_client.upload_blob(data) + print(f"Uploaded {file_name}.") + + +def load_files_blob(): + container_client = blob_service_client.get_container_client(CONTAINER_NAME) + files_name = [] + for blob in container_client.list_blobs(): + files_name.append(blob.name) + return files_name + + +def delete_blob(blob_name): + # Get container client + container_client = blob_service_client.get_container_client(CONTAINER_NAME) + + container_client.delete_blob(blob_name) + print(f"Deleted {blob_name}") + def delete_all(): - for files in os.listdir(SAVE_DIR): - os.remove(os.path.join(SAVE_DIR, files)) - index.delete(delete_all=True) - message = "Delete all files succesfully" + container_client = blob_service_client.get_container_client(CONTAINER_NAME) + blob_list = container_client.list_blobs() + + for blob in blob_list: + container_client.delete_blob(blob.name) + index.delete(delete_all=True, namespace=NAME_SPACE_1) + message = f"Delete all files in space {NAME_SPACE_1} succesfully" return gr.update(choices=[]), message, gr.Files.update(None) def delete_file(files_src): file_name = [] for files in files_src: - os.remove(os.path.join(SAVE_DIR, files)) + delete_blob(files) file_name.append(files) - _filter = {"document_id": {"$in": file_name}} - index.delete(filter=_filter) - message = f"Delete {len(files_src)} files succesfully" - return gr.update(choices=os.listdir(SAVE_DIR)), message, gr.Files.update(None) - -def upload_file(): - vectorstore = Pinecone.from_existing_index(INDEX_NAME, embeddings) - print(f"Load files from existing {INDEX_NAME}") + _filter = {"source": {"$in": file_name}} + index.delete(filter=_filter, namespace=NAME_SPACE_1) + message = f"Delete {len(files_src)} files in space {NAME_SPACE_1} files succesfully" + available_files = load_files_blob() + return gr.update(choices=available_files), message, gr.Files.update(None) + +def upload_file(check_box): + if check_box: + namespace = NAME_SPACE_1 + else: + namespace = NAME_SPACE_2 + vectorstore = Pinecone.from_existing_index(INDEX_NAME, embeddings, namespace=namespace) + print(f"Load files from space {namespace} in {INDEX_NAME}") return vectorstore - def handle_upload_file(files): documents = get_documents(files) if len(documents)>0: - Pinecone.from_documents(documents, embeddings, index_name=INDEX_NAME) - message = f"Add files to {INDEX_NAME} sucessfully" + Pinecone.from_documents(documents, embeddings, index_name=INDEX_NAME, namespace=NAME_SPACE_1) + message = f"Add files to space {NAME_SPACE_1} in {INDEX_NAME} sucessfully" print(message) else: - message = f"Load files from existing {INDEX_NAME}" + message = f"Load files from space existing {NAME_SPACE_1} in {INDEX_NAME}" print(message) return message -def update_file(): - with open('data.json') as json_file: - data = json.load(json_file) - datas = ast.literal_eval(data) - - texts = [] - for k, v in datas.items(): - content = v["content"] - post_url = v["post_url"] - texts.append(Document(page_content=content, metadata={"source": post_url})) - - if len(texts)>0: - Pinecone.from_documents(texts, embeddings, index_name=INDEX_NAME) - message = f"Add facebook data to {INDEX_NAME} sucessfully" - return message def get_documents(file_src): documents = [] if file_src is None: return documents + available_files = load_files_blob() for file in file_src: filepath = file.name filename = os.path.basename(filepath) file_type = os.path.splitext(filename)[1] - if filename in os.listdir(SAVE_DIR): + if filename in available_files: continue else: - shutil.copy(filepath, os.path.join(SAVE_DIR, filename)) + upload_files_blob(filepath) try: if file_type == ".pdf": pdftext = "" @@ -124,7 +156,7 @@ def get_documents(file_src): pdf_reader = PyPDF2.PdfReader(pdfFileObj) for page in tqdm(pdf_reader.pages): pdftext += page.extract_text() - texts = [Document(page_content=pdftext, metadata={"source": filepath})] + texts = [Document(page_content=pdftext, metadata={"source": filename})] elif file_type == ".docx": from langchain.document_loaders import UnstructuredWordDocumentLoader loader = UnstructuredWordDocumentLoader(filepath) diff --git a/website/http___www.mbpp.gov.my__ms_bantuan.html b/website/http___www.mbpp.gov.my__ms_bantuan.html deleted file mode 100644 index b0acc511e67fe89fc574724a730fb27dcf4d135a..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_bantuan.html +++ /dev/null @@ -1,1157 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Bantuan | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
-
-
- - -
-
- - -
-
- - - - -
-
-

W3C

-

Portal MBPP menyediakan kemudahan untuk capaian Orang Kurang Upaya (OKU) / Disability Access seperti berikut :

-

1. Bagi pengguna warga tua, Portal Rasmi MBPP ada menyediakan kemudahan pilihan saiz teks yang berbeza. Pilihan saiz teks tersebut dipaparkan di ruangan atas setiap halaman Portal Rasmi MBPP. Pengguna boleh memilih samada untuk memilih saiz teks yang lebih besar atau lebih kecil, mengikut kesesuaian.

-

Pengguna warga tua

-

2. Pengguna buta warna

-

Bagi pengguna buta warna, terdapat beberapa pilihan warna disediakan diruangan atas setiap halaman Portal Rasmi MBPP. Pengguna boleh memilih warna daripada seleksi warna yang disediakan samada biru, merah atau hijau.

-

Buta warna

-

3. Pengguna cacat penglihatan

-

Bagi pengguna yang cacat penglihatan, terdapat pembaca teks (text reader) di dalam Portal Rasmi MBPP. Kemudahan pembaca text (text reader) akan menjana suara secara automatik sebagai alternatif kepada pengguna cacat penglihatan dimana mereka boleh mendengar dengan jelas isi kandungan yang ingin disampaikan. Panduan untuk menggunakan kemudahan ini adalah seperti berikut: Semasa melayari laman ini, anda akan menemui ikon "Dengar text Dengar teks" pada bahagian atas portal ini. Klik padanya dan satu tetingkap baru akan muncul. Paparan tersebut adalah seperti dibawah :

-
-
-

BANTUAN KOD QR

-

i. Memuat turun aplikasi QR Reader yang bersesuaian dengan Smartphone anda
ii. Pilih dan aktifkan aplikasi QR Reader dan kemudian imbas Kod QR di tepi peta lokasi MBPP dengan menggunakan kamera dari Smartphone anda.
iii. Anda akan terus dibawa ke lokasi Google maps MBPP dalam versi mudah alih.

-
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_dasar-keselamatan.html b/website/http___www.mbpp.gov.my__ms_dasar-keselamatan.html deleted file mode 100644 index 21f417c44d378f3eac3077ce46f6064eb128e61d..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_dasar-keselamatan.html +++ /dev/null @@ -1,1146 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Dasar Keselamatan | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
-
-
- - -
-
- - -
-
- - - - -
-

Perlindungan Data

-

Teknologi terkini termasuk penyulitan data adalah digunakan untuk melindungi data yang dikemukakan dan pematuhan kepada standard keselamatan yang ketat adalah terpakai untuk menghalang capaian yang tidak dibenarkan.

-

Keselamatan Storan

-

Semua storan elektronik dan penghantaran data peribadi akan dilindungi dan disimpan dengan menggunakan teknologi keselamatan yang sesuai.

-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_dasar-privasi.html b/website/http___www.mbpp.gov.my__ms_dasar-privasi.html deleted file mode 100644 index e0456e7a3eafddd0f68e345559535f25f0d9bd7f..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_dasar-privasi.html +++ /dev/null @@ -1,1154 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Dasar Privasi | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
-
-
- - -
-
- - -
-
- - - - -
-

Privasi anda

-

Halaman ini menerangkan dasar privasi yang merangkumi penggunaan dan perlindungan maklumat yang dikemukakan oleh pengunjung.

-

Sekiranya anda membuat transaksi atau menghantar e-mel yang mengandungi maklumat peribadi, maklumat ini mungkin akan dikongsi bersama dengan agensi awam lain untuk membantu penyediaan perkhidmatan yang lebih berkesan dan efektif. Contohnya seperti di dalam menyelesaikan aduan yang memerlukan maklum balas dari agensi-agensi lain.

-

Maklumat Yang Dikumpul

-

Tiada maklumat peribadi akan dikumpul semasa anda melayari laman web ini kecuali maklumat yang dikemukakan oleh anda melalui e-mel.

-

Apa yang akan Berlaku jika Saya Membuat Pautan kepada Laman Web yang Lain?

-

Laman web ini mempunyai pautan ke laman web lain. Dasar privasi ini hanya terpakai untuk laman web ini sahaja. Perlu diingatkan bahawa laman web yang terdapat dalam pautan mungkin mempunyai dasar privasi yang berbeza dan pengunjung dinasihatkan supaya meneliti dan memahami dasar privasi bagi setiap laman web yang dilayari.

-

Pindaan Dasar

-

Sekiranya dasar privasi ini dipinda, pindaan akan dikemas kini di halaman ini. Dengan sering melayari halaman ini, anda akan dikemas kini dengan maklumat yang dikumpul, cara ia digunakan dan dalam keadaan tertentu, bagaimana maklumat dikongsi bersama pihak yang lain.

-


-
-

-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_mbpp_pengurusan_perutusan-datuk-bandar.html b/website/http___www.mbpp.gov.my__ms_mbpp_pengurusan_perutusan-datuk-bandar.html deleted file mode 100644 index c5f1870f5edd479894236b30159f3723f5e0fa17..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_mbpp_pengurusan_perutusan-datuk-bandar.html +++ /dev/null @@ -1,1257 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Perutusan Datuk Bandar | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-

TEKS UCAPAN YBHG. DATO’ IR. RAJENDRAN A/L P. ANTHONY DATUK BANDAR MAJLIS BANDARAYA PULAU PINANG DI UPACARA PENGAKUAN PENERIMAAN JAWATAN DATUK BANDAR MAJLIS BANDARAYA PULAU PINANG PADA 9 MEI 2023 (SELASA), JAM 9.30 PAGI BERTEMPAT DI DEWAN PERSIDANGAN MAJLIS, DEWAN BANDARAYA, JALAN PADANG KOTA LAMA, PULAU PINANG

-
-

Yang Amat Berhotmat Tuan Chow Kon Yeow

-

Ketua Menteri Pulau Pinang,

-

 

-

Yang Berhormat Dato' Ir. Haji Ahmad Zakiyuddin bin Abd Rahman,

-

Timbalan Ketua Menteri (I) Pulau Pinang,

-

 

-

Yang Berhormat Prof. Dr. P. Ramasamy a/l Palanisamy,

-

Timbalan Ketua Menteri (II) Pulau Pinang,

-

 

-

Yang Berhormat Dato' Mohd Sayuthi bin Bakar,

-

Setiausaha Kerajaan Negeri Pulau Pinang,

-

 

-

Yang Berhormat

-

Tuan Jagdeep Singh Deo a/l Dato Seri Utama Karpal Singh,

-

Ahli Mesyuarat Kerajaan Negeri Pulau Pinang

-

Merangkap Pengerusi Jawatankuasa Perumahan, Kerajaan Tempatan,

-

Perancangan Bandar & Desa,

-

 

-

Yang Berhormat-Yang Berhormat,

-

Ahli- Ahli Majlis Mesyuarat Kerajaan Negeri Pulau Pinang,

-

 

-

Yang Berhormat-Yang Berhormat,

-

Ahli-Ahli Parlimen dan Ahli-Ahli Dewan Undangan Negeri Pulau Pinang dan,

-

 

-

Ahli-Ahli Majlis,

-

Majlis Bandaraya Pulau Pinang,

-

 

-

Ketua-ketua Jabatan,

-

 

-

Rakan-rakan Media,

-

 

-

Tuan-tuan dan Puan-puan yang saya hormati sekalian,

-

 

-

Selamat pagi, salam sejahtera, Salam Malaysia Madani dan Salam Penang2030

-

 

-

Terlebih dahulu saya ingin mengucapkan terima kasih ke atas kehadiran  Yang Berhormat/ Dato’/ Tuan-tuan dan Puan-Puan pada pagi yang mulia ini.

-

 

-

Saya telah dilahirkan di Pulau Pinang tidak sampai 60 tahun yang lalu. Majlis Bandaraya Pulau Pinang telah menjadi sebahagian daripada hidup saya sejak tahun 1986 apabila saya melaporkan diri untuk bertugas di Jabatan Kejuruteraan pada usia 23 tahun. Kini, selepas berkhidmat 37 tahun di Majlis, saya berdepan dengan tuan-tuan dan puan-puan untuk pelantikan saya sebagai Datuk Bandar, Majlis Bandaraya Pulau Pinang.  

-

 

-

Walaupun tidak terlintas di fikiran saya pada satu ketika dahulu bahawa saya akan diberi tanggungjawab ini, pelantikan saya membuktikan bahawa di bawah Kerajaan Negeri ini, peluang terbuka kepada sesiapa pun yang berkomited. Untuk ini, saya amat berterima kasih kepada Kerajaan Negeri Pulau Pinang di bawah pimpinan YAB Tuan Chow Kon Yeow serta barisan Ahli-ahli Majlis Mesyuarat Kerajaan Negeri Pulau Pinang kerana memberi kepercayaan kepada saya. Sebutan khas juga kepada keluarga saya yang banyak bersabar serta Ahlimajlis-ahlimajlis ke atas sokongan padu; dan yang penting warga MBPP yang telah menunjukkan semangat kerja berpasukan yang saya sanjungi. Saya bangga menjadi salah seorang warga MBPP dan warga pelbagai etnik Negeri Pulau Pinang dan Malaysia.

-

 

-

Saya diberi tanggungjawab ini pada masa Negeri Pulau Pinang sedang mengalami pembangunan yang menggalakkan. Seiring dengan pembangunan ini, permintaan, kehendak dan keperluan penduduk termasuk  perniagaan dan industri telah meningkat. MBPP menjadi titik hubungan pertama dan secara langsung berdepan dengan isu-isu dan masalah yang dihadapi oleh penduduk dan semua pemegang taruh (stakeholders). Dalam soal ini, MBPP bersedia mendengar suara rakyat dan menjalinkan ikatan kerjasama untuk memberi perkhidmatan dan melaksanakan inisiatif-inisiatif yang membawa manafaat kepada semua pihak. Melalui perbelanjaan yang berhemah, saya yakin harapan dan aspirasi penduduk dapat dipenuhi secara progresif.

-

 

-

Isu-isu utama yang diketahui umum dan sedang diberi perhatian yang yang serius adalah kebersihan dan kesesakan lalulintas. Saya ingin mengesahkan bahawa perancangan dan langkah-langkah penambahbaikan sedang dilaksanakan dan akan dipertingkatkan. Di samping ini, proses pendidikan dan tindakan penguatkuasaan akan diteruskan.

-

 

-

Untuk menangani masalah kebersihan dan pemungutan sampah, MBPP telah memperkenalkan cara-cara yang lebih sistematik yang akan ditambahbaik melalui penggunaan teknologi terkini. Pasukan khas juga telah diadakan untuk mengambil tindakan segera ke atas sebarang aduan yang diterima dan memberi perkhidmatan sokongan sekiranya diperlukan. Seiring dengan ini, Majlis telah memperkukuhkan tenaga kerja dengan melantik 150 orang pekerja pembersihan pada tahun 2023 dan tindakan sedang diambil untuk menambah 10 buah kenderaan compactor unit. Di samping ini, untuk mengurangkan kuantiti sisa pepejal yang dilupuskan, pengitaran semula melalui Projek Waste to Energy akan dijalankan pada tahun 2024 di mana kadar kitar semula di bahagian pulau, Pulau Pinang dijangka dapat menjangkaui 60%.

-

 

-

Dari segi lalulintas, pelan-pelan menaiktaraf jalan dan membina infrastruktur jalan yang penting akan diteruskan dan pada masa yang sama tumpuan akan diberi kepada penggunaan pengangkutan awam dan pengangkutan alternatif.  Selain daripada ini, initiatif-initiatif untuk menggalakkan lebih ramai orang berjalan kaki untuk perjalanan dekat akan dilaksanakan. Ruang jalan juga semakin terhad dengan pertambahan kenderaan dan pejalan kaki terutama sekali di kawasan pusat bandar di mana jalan-jalan tidak dapat dilebarkan lagi.

-

Keadaan kesesakan bukan hanya tertumpu kepada waktu-waktu puncak lalulintas malah menjadi lebih runcing pada musim cuti dan hujung minggu. Oleh yang demikian, penggunaan ruang jalan perlu dioptimakan mengikut keutamaan dan secara saksama melalui perancangan yang lebih menyeluruh dan dihalusi melalui proses libat urus dengan orangramai.

-

 

-

Pelan-pelan dan tindakan untuk memperkukuhkan lagi kedayatahanan dan kesiapsagaan kita dalam menghadapi sebarang situasi, gejala atau bencana alam terutama sekali kesan perubahan iklim juga telah diberi perhatian. Ia melibatkan pembangunan strategi menyeluruh dengan kerjasama pelbagai pemegang taruh bersama agensi-agensi kerajaan secara bersepadu. Pada masa yang sama, langkah-langkah jangka masa pendek dan panjang telah diadakan untuk menangani kesan perubahan iklim seperti kejadian banjir, kemungkinan tanah runtuh, peningkatan suhu dan lain-lain. Sehubungan ini, UN-Habitat telah memilih Pulau Pinang untuk menerima dana sebanyak USD10.0 juta untuk pelaksanaan Nature Based Climate Adaptation Program selama 5 tahun mulai tahun 2023 bersama rakan-rakan strategik Kerajaan Negeri dan MBPP yang melibatkan projek-projek dan program menghijaukan bandar, pengurusan air larian hujan dan kedayatahanan sosial. Sejajar dengan halatuju Bandar Rendah Karbon (Low Carbon City) dan sasaran Neutral Karbon (Net Zero) menjelang 2050, banyak usaha telah diambil untuk mengurangkan pelepasan karbon dan menggunapakai tenaga semula jadi serta mengekalkan kelestarian alam sekitar seperti penukaran kesemua 33,000 lampu jalan di bahagian pulau, Pulau Pinang ke jenis LED dan penggunaan lampu cekap tenaga di semua premis MBPP. Tenaga solar juga digunakan di tujuh (7) buah bangunan kepunyaan MBPP dan pencahayaan laluan-laluan khas basikal.

-

Usaha-usaha ini telah mengurangkan pelepasan lebih kurang 11,100 ton metrik karbon setahun dan penjimatan RM4.29 juta duit rakyat setahun. Sepastinya, projek-projek dan program ini yang sebahagiannya dijalankan melalui public private partnership dan private finance initiative akan diteruskan.

-

 

-

MBPP juga berupaya mengikuti perkembangan arus Evolusi Digital yang telah memberi impak positif kepada cara MBPP mengurus dan mentadbir bandar. Sebanyak 112 urusan pembayar cukai MBPP boleh dijalankan secara dalam talian manakala pembayaran secara tanpa tunai telah digunakan untuk 86% daripada transaksi dengan MBPP pada tahun 2023. Projek Transformasi Digital melalui pembangunan SmiDat (Smart Island Digital Twin) akan diperkasakan sehingga disempurnakan pada tahun 2025. Dua komponen penting SmiDat adalah pembangunan model maya bandar sebagai klon digital kepada realiti (Virtual City model) serta pemasangan rangkaian fiber eksklusif sekeliling bahagian pulau, Pulau Pinang. Sehubungan dengan ini, MBPP memberi sokongan penuh kepada Digital Nasional Berhad (DNB) dalam penyediaan rangkaian 5G yang dapat membantu merealisasikan potensi penuh Industri 4.0 yang sangat penting bagi Pulau Pinang. Kemudahan 5G dijangka mencapai liputan melebihi 90% di kawasan berpenduduk di Negeri Pulau Pinang pada akhir tahun tahun 2023. Seterusnya kita bersedia melangkah ke Machine Learning dan Artificial Intelligence termasuk Generative Pretrained Transformer yang lebih dikenali sebagai Chat-GPT supaya pengurusan bandar menjadi lebih efisyen dan efektif serta progresif dan berdaya saing.

-

 

-

Tidak ketinggalan juga warga berusia dan kelainan upaya di Pulau Pinang. Penuaan masyarakat adalah kepastian demografi yang tidak dapat diabaikan dan perlu didepani, disesuaikan dan dipermudah. Mengikut statistik semasa, lebih daripada 16% daripada penduduk Pulau Pinang berada dalam lingkungan umur 60 tahun atau lebih. Angka ini dijangka mencecah 26.2% menjelang tahun 2040 iaitu di antara yang tertinggi di Malaysia. Sehubungan ini, MBPP telah memohon untuk menjadi Ahli WHO Global Network of Age-Friendly Cities and Communities yang menggalakkan penuaan sihat dan selamat serta menjadikan warga berusia lebih inklusif dalam komuniti. MBPP telah menyediakan infrastuktur dan kemudahan yang bersesuaian berpandukan rekabentuk sejagat (universal design) yang sedang diperluaskan secara berperingkat. Akan tetapi, yang lebih penting adalah memastikan warga berusia dan kelainan upaya dapat menyumbang kepada komuniti dan menjalani hidup yang bermakna.

-

 

-

Visi Penang2030 yang diilhamkan oleh YAB Ketua Menteri Pulau Pinang akan terus menjadi tunjang, dihayati dan dijadikan panduan kepada penetapan halatuju MBPP ke arah sebuah Negeri Pintar dan Hijau Berteraskan Keluarga Inspirasi Negara. Penerapan Matlamat Pembangunan Mampan (Sustainable Development Goals) menjadi intipati kepada pencapaian Visi Penang2030 dan pelaksanaan projek, program dan perkhidmatan MBPP. MBPP menyahut seruan pelaksanaan initiatif-initiatif place making, pembangunan komuniti dan penglibatan industri yang digariskan dalam Penang2030 dengan memberi perhatian kepada tahap Index Kebahagiaan Negeri Pulau Pinang yang berada pada peratusan 76.5% mengikut kajian pada tahun 2021 dan mengatasi index purata Negara.

-

 

-

MBPP juga akan akur kepada halatuju Negara dalam konteks Kerajaan Tempatan yang ditetapkan Menteri Pembangunan Kerajaan Tempatan, YB Nga Kor Ming.

-

 

-

Saya berserta warga MBPP juga ingin menzahirkan setinggi-tinggi penghargaan dan ucapan terima kasih kepada mantan Datuk Bandar MBPP, Dato’ Yew Tung Siang yang menerajui MBPP untuk tempoh melebihi 5 tahun. Banyak perkataan yang boleh digunakan untuk menggambarkan atau menghuraikan beliau, di antaranya adalah ceria, tegap dan bertenaga. Di nota yang lebih serius beliau adalah seorang yang cekal, berkebolehan dan berwawasan. Jasa dan budi Dato’ Yew Tung Siang adalah tidak terukur dan beliau telah menyediakan satu pelantar dan landasan yang kukuh untuk membolehkan saya mengambil alih tugas-tugas Datuk Bandar.

-

 

-

Akhirkata, saya berdoa agar Tuhan memberikan kekuatan, ketabahan dan kesabaran kepada saya untuk menjalankan tugas dan tanggungjawab sebagai Datuk Bandar dengan sebaik mungkin serta menghadapi cabaran-cabaran yang sepastinya wujud. Saya yakin dan percaya bahawa dengan iltizam, iktibar dan semangat tidak putus asa saya bersama warga MBPP, kita dapat memenuhi aspirasi rakyat Pulau Pinang serta menunaikan amanat Kerajaan Negeri.

-

 

-

Sekian, terima kasih.

-

 

-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_node_2490.html b/website/http___www.mbpp.gov.my__ms_node_2490.html deleted file mode 100644 index 02fee009efafebb3ae0cb1758fca0a999a3ec3d4..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_node_2490.html +++ /dev/null @@ -1,1148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - AGE FRIENDLY CITY SURVEY | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
-
-
- - -
-
- - -
-
- - - - -
-

We (the Malaysian Healthy Ageing Society and Penang Women's Development Corporation [PWDC]) call on all Penangites to participate in a state government plan to make Penang an Age-Friendly City. This refers to Penang’s initiative to be an Age-Friendly City for all young, older, and people with disabilities to access outdoor spaces, transportation, housing, social activities, communication, information, community support, and health services.

-

Your feedback matters and will help align the government initiatives driven by community voices (i.e. your voice/opinion/say).

-

Help us by clicking on the following link to access the survey – it will take approximately 20 to 30 minutes – depending on your internet speed. Upon completion, please hit the submit button and help us disseminate the survey (with the above msg) to all who work and reside in Penang Island.

-

English Version of the Survey: https://forms.gle/UKKruubhbmxAvnPp9

-

 

-

-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_pelawat_destinasi-menarik.html b/website/http___www.mbpp.gov.my__ms_pelawat_destinasi-menarik.html deleted file mode 100644 index d52970782dacf96e1cdcb701a4018384776a884a..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_pelawat_destinasi-menarik.html +++ /dev/null @@ -1,1263 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Destinasi Menarik | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Bukit Bendera

-
-

-

-

-
  -

 

-

Buat pengunjung yang pertama kali ke Pulau Pinang seharusnya menjejakkan kaki mereka ke sini.

-

 

-

 

-

Pemandangan dari atas bukit dan panoramanya amat menarik sekali.

-

 

-

Jadual waktu keretapi bergerak - Waktu keretapi bertolak dari bawah : 6.30 am (cuti) 7.00am hari biasa dan setiap setengah jam hingga jam 9.00 pm. Sabtu : 6.30am, 6.45am, 7.00am dan setiap setengah jam hingga jam 11.00pm Tiket untuk dewasa RM4 (pergi balik / return) manakala untuk kanak-kanak 12 tahun kebawah RM2 (pergi balik / return).

-
 
-

Taman Negara

-
-

-

-

-
  -

 

-

 

-

 

-

 

-

Taman Negara Pulau Pinang terletak di Teluk Bahang, Daerah Barat Daya. Jaraknya dari bandar Georgetown adalah lebih kurung 20 kilometer. Taman negara ini adalah seluas 1381 hektar yang merangkumi keluasan daratan dan lautan yang telah digazetkan.

-
 
-

Jambatan Pulau Pinang

-
-

-

-
  -

Jambatan Pulau Pinang merupakan jambatan yang terpanjang di Asia Tenggara. Kerja pembinaan bermula pada tahun 1982 dan siap dibina pada tahun 1985, iaitu memakan masa selama 3 tahun untuk disiapkan dan dengan kos sebanyak RM 850 juta.

-

Jambatan ini membawa kebanggaan kepada negara dan ketiga terpanjang di dunia. Ia adalah sepanjang 13.5 kilometer di mana 8.4 kilometer daripadanya merentasi laut. Ia menghubungkan bahagian pulau dengan tanah besar di semenanjung.

-
 
-

Komtar

-
-

-
 Menara KOMTAR (Kompleks Tun Abdul Razak) terletak di Georgetown, Pulau Pinang. Menara KOMTAR merupakan bangunan tertinggi di Pulau Pinang dan ke-6 di Malaysia. Bangunan ini berbentuk segi 12. Bangunan yang menempatkan ruang pejabat ini mempunyai ketinggian 232m atau 760 kaki dan mempunyai 65 tingkat kesemuanya.
 
-

Batu Feringgi

-
-

-

-
  -

 

-

 

-

Batu Feringgi terletak di sepanjang jalan pesisiran barat laut bandar Georgetown dan dipenuhi dengan resort bertaraf antarabangsa, dan merupakan pantai paling popular di Pulau Pinang.

-
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_pelawat_destinasi-menarik_peta-destinasi-menarik.html b/website/http___www.mbpp.gov.my__ms_pelawat_destinasi-menarik_peta-destinasi-menarik.html deleted file mode 100644 index dbc910c9b701af1af828630f7a1f7462bd09be79..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_pelawat_destinasi-menarik_peta-destinasi-menarik.html +++ /dev/null @@ -1,1204 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Peta Destinasi Menarik | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-

-
-
-
-
-
-
-
-

-
-
- -
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

 

-

Museum and Art Galery

-

-

Penang Street Art

-

-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_pelawat_info-pulau-pinang.html b/website/http___www.mbpp.gov.my__ms_pelawat_info-pulau-pinang.html deleted file mode 100644 index 9a80535323c12ae8c7e249b47f5faa9e7e10252e..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_pelawat_info-pulau-pinang.html +++ /dev/null @@ -1,1164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Info Pulau Pinang | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-

Portal Rasmi Kerajaan Negeri Pulau Pinang

-

-

Penang GeoHub

-

-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_pelawat_pengangkutan.html b/website/http___www.mbpp.gov.my__ms_pelawat_pengangkutan.html deleted file mode 100644 index 587cc26a97f770890fe89565eb3f39f4927fd784..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_pelawat_pengangkutan.html +++ /dev/null @@ -1,1191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Pengangkutan | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-

PENGANGKUTAN AWAM

-

PENYEDIAAN SEMULA PERKHIDMATAN BAS CENTRAL AREA TRANSIT (CAT) TANPA TAMBANG DI KAWASAN PUSAT BANDAR GEORGE TOWN, PULAU PINANG

-

Pengenalan

-

Perkhidmatan Bas Central Area Transit (CAT) telah diwujudkan semula sejak 23 Februari 2009 untuk meningkatkan semula kualiti hidup dan kerja di kawasan bandar serta mengurangkan pencemaran udara, bunyi, pembaziran bahanapi (petrol dan diesel) dan kesesakan lalulintas. Di samping ini perkhidmatan Bas CAT diperlukan untuk menggalak dan meningkatkan penggunaan perkhidmatan pengangkutan awam di Pulau Pinang.

-

Ciri-Ciri Perkhidmatan

-

Ciri-ciri perkhidmatan Bas CAT yang disediakan oleh MPPP adalah seperti berikut (risalah bas disertakan):-

-
    -
  1. -

    Tiada bayaran tambang dikenakan.

    -
  2. -
  3. -

    Laluan bas adalah dari Pengkalan Weld (Feri) ke Komtar sejauh 8 km (pergi balik) dengan 19 perhentian bas yang meliputi kawasan seluas 1 km persegi.

    -
  4. -
  5. -

    Waktu perkhidmatan adalah dari 6.00 pagi hingga 12.00 malam setiap hari termasuk hujung minggu dan cuti umum.

    -
  6. -
  7. -

    3 buah bas digunakan untuk menyediakan perkhidmatan ini dan perselangan masa perjalanan adalah 20 minit secara purata.

    -
  8. -
  9. -

    Bas-bas yang digunakan adalah dari jenis low floor dan panjang bas adalah 10 meter. Semua bas dilengkapi dengan sistem hawa dingin dan tempat duduk disediakan untuk orang kurang upaya.

    -
  10. -
  11. -

    Kapasiti bas adalah 49 penumpang dengan 29 penumpang duduk dan 20 berdiri.

    -
  12. -
-

Tiga buah bas Rapid Penang yang digunakan untuk perkhidmatan CAT telah diberi wajah baru dengan paparan gambar-gambar pada badan bas untuk membezakannya dengan bas-bas lain.

-

-

 

-

Peta & Laluan Bas "CAT"

-

-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_akta.html b/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_akta.html deleted file mode 100644 index bf7841dccb5cb3213ceeeebdbf02d03fc15b53de..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_akta.html +++ /dev/null @@ -1,1198 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Akta | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_enakmen.html b/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_enakmen.html deleted file mode 100644 index 6edbf065894aa2a5552592a60c669b1413acf168..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_enakmen.html +++ /dev/null @@ -1,1182 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Enakmen | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
- -
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_undang-undang-kecil.html b/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_undang-undang-kecil.html deleted file mode 100644 index 7e6249ca229d7301c0c4d6b7ef96ba2c8bea4af2..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_perniagaan_perundangan_undang-undang-kecil.html +++ /dev/null @@ -1,1219 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Undang-undang Kecil | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-
-
    -
  1. By-laws for the licensing of Bullock Cart Drivers, 1918
  2. -
  3. By-laws for the Regulation of the Transport and Storage of Petroleum and Dangerous Petroleum, 1931
  4. -
  5. By-laws with respect to Places of Public Entertainment, 1933
  6. -
  7. The Prevention of Cruelty to Animals By-laws, 1947
  8. -
  9. Penang Municipal Trisha By-laws, 1948
  10. -
  11. Penang Municipal (Garages) By-laws, 1952
  12. -
  13. Penang (Municipal) Tricycle By-laws, 1953
  14. -
  15. Penang (Municipal) Fees Title By-laws, 1953
  16. -
  17. Rural District Council, Penang Island, Sewage Purification Plants By-laws, 1957
  18. -
  19. Rural District Council, Penang Island, Dangerous, Unhealthy or Offensive Trades and Garages By-laws, 1962 [Dimansuhkan: Jadual Bahagian A, B & D sahaja - Lihat Undang-Undang Kecil (Tred, Perniagaan & Industri) 1991]
  20. -
  21. Undang-Undang Kecil (Lembu-Kerbau) Bandaraya George Town, Pulau Pinang, 1968
  22. -
  23. Undang-Undang Kecil (Pemasangan Sistem Saluran Najis dan Alat-alat Kebersihan), 1970 Majlis Bandaraya George Town
  24. -
  25. City of Georgetown, Penang, Liquefied Petroleum Gases By-laws, 1971
  26. -
  27. Undang-Undang Kecil Kerja-kerja (Pembinaan) Jalan Baru Majlis Bandar Raya, 1971
  28. -
  29. Undang-Undang Kecil (Lembu-kerbau) Majlis Daerah Luar Bandar, Pulau Pinang, 1972
  30. -
  31. Undang-Undang Kecil (Kerjatanah), Pulau Pinang 1975
  32. -
  33. Undang-Undang Kecil (Pengimpotan Daging) Majlis Perbandaran Pulau Pinang, 1977
  34. -
  35. Undang-Undang Kecil (Mengkompaun Kesalahan-kesalahan) Majlis Perbandaran Pulau Pinang, 1977
  36. -
  37. Undang-Undang Kecil (Anjing-anjing) Majlis Perbandaran Pulau Pinang, 1977 [Undang-Undang Kecil (Anjing-anjing)(Pindaan) 1985]
  38. -
  39. Undang-Undang Kecil (Larangan Merokok Dalam Panggungwayang-panggungwayang) Majlis Perbandaran Pulau Pinang, 1978
  40. -
  41. Undang-Undang Kecil Penjaja-penjaja, 1979 [Undang-Undang Kecil (Pindaan) Penjaja-penjaja, 1987] [Undang-Undang Kecil Penjaja-penjaja (Pindaan) 1991]
  42. -
  43. Undang-Undang Kecil (Gadi-Gadi) Majlis Perbandaran Pulau Pinang, 1979
  44. -
  45. Undang-Undang Kecil (Rumah-Rumah Sembelih) Majlis Perbandaran Pulau Pinang, 1979
  46. -
  47. Undang-Undang Kecil (Rumah Urut) Majlis Perbandaran Pulau Pinang, 1980
  48. -
  49. Undang-Undang Kecil (Kebersihan dan Keselamatan Awam) Majlis Perbandaran Pulau Pinang, 1980
  50. -
  51. Undang-Undang Kecil Pasar-Pasar, 1980, Majlis Perbandaran Pulau Pinang
  52. -
  53. Undang-Undang Kecil (Balai Rakyat Padang Tembak) Majlis Perbandaran Pulau Pinang, 1980
  54. -
  55. Undang-Undang Kecil (Larangan Merokok Di Dalam Kenderaan-Kenderaan Perkhidmatan Awam) 1980
  56. -
  57. Undang-Undang Kecil (Rumah Bantai Perbandaran) Majlis Perbandaran Pulau Pinang, 1980 [Undang-Undang Kecil (Rumah Bantai Perbandaran) Majlis Perbandaran Pulau Pinang (Pindaan) 1997]
  58. -
  59. Undang-Undang Kecil (Mengkompaun Kesalahan-Kesalahan) Jalan, Parit dan Bangunan, 1980
  60. -
  61. Undang-Undang Kecil Bayaran Pelan, 1981
  62. -
  63. Undang-Undang Kecil (Pengendali Makanan) Majlis Perbandaran Pulau Pinang, 1983
  64. -
  65. Undang-Undang Kecil (Bangunan Seragam) Majlis Perbandaran Pulau Pinang, 1984
  66. -
  67. Undang-Undang Kecil (Bayaran-bayaran Stadium) Majlis Perbandaran Pulau Pinang, 1986 [Undang-Undang Kecil (Pindaan) (Bayaran-Bayaran Stadium) Majlis Perbandaran Pulau Pinang, 1988]
  68. -
  69. Undang-Undang Kecil (Memelihara Babi) Majlis Perbandaran Pulau Pinang, 1987
  70. -
  71. Undang-Undang Kecil (Tempat Letak Kereta Persendirian) Majlis Perbandaran Pulau Pinang, 1988
  72. -
  73. Undang-Undang Kecil (Iklan Pilihanraya) Majlis Perbandaran Pulau Pinang, 1990
  74. -
  75. Undang-Undang Kecil (Establisymen Makanan) Majlis Perbandaran Pulau Pinang, 1991
  76. -
  77. Undang-Undang Kecil (Tred, Perniagaan dan Perindustrian) Majlis Perbandaran Pulau Pinang, 1991
  78. -
  79. Undang-Undang Kecil (Taman) (Majlis Perbandaran Pulau Pinang), 1993
  80. -
  81. Undang-Undang Kecil Majlis Perbandaran Pulau Pinang (Tandas Awam) 1993
  82. -
  83. Undang-Undang Kecil (Iklan) Majlis Perbandaran Pulau Pinang, 2000
  84. -
  85. Undang-Undang Kecil Pengasingan Sampah Dan Pelesenan Perkhidmatan Pemungutan Sampah Yang Boleh Dikitar Semula (Majlis Bandaraya Pulau Pinang) 2016
  86. -
-
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_perniagaan_senarai-pasar-malam-pasar-kompleks-makanan-dan-tapak-penjaja.html b/website/http___www.mbpp.gov.my__ms_perniagaan_senarai-pasar-malam-pasar-kompleks-makanan-dan-tapak-penjaja.html deleted file mode 100644 index f495a175370f3d8c4335c7c1e89cb947211e897c..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_perniagaan_senarai-pasar-malam-pasar-kompleks-makanan-dan-tapak-penjaja.html +++ /dev/null @@ -1,1191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Senarai Pasar Malam, Pasar, Kompleks Makanan dan Tapak Penjaja | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-

1) Senarai Pasar Malam/Pagi/Minggu/Tani mengikut Daerah

- -

2) Senarai Pasar mengikut Daerah beserta maklumat kekosongan

- -

3) Senarai Kompleks Makanan mengikut Daerah beserta maklumat kekosongan

- -

4) Senarai Tapak Penjaja mengikut Daerah beserta maklumat kekosongan

- -
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_rakyat_perkhidmatan_penilaian-harta.html b/website/http___www.mbpp.gov.my__ms_rakyat_perkhidmatan_penilaian-harta.html deleted file mode 100644 index e717de76b34fa3535a95c5531e5a591d0961bc9a..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_rakyat_perkhidmatan_penilaian-harta.html +++ /dev/null @@ -1,1317 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Penilaian Harta | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-

Kadar (Cukai Taksiran atau Cukai Pintu)

-
    -
  • -

    Pengenalan

    -
  • -
  • -

    Nilai Tahunan

    -
  • -
  • -

    Kadar Peratus

    -
  • -
  • -

    Kawasan Kadaran

    -
  • -
  • -

    Tarikh Cukai Taksiran Dikenakan

    -
  • -
  • -

    Bantahan Kepada Cadangan Nilai Tahunan

    -
  • -
  • -

    Pengecualian Dari Membayar Kadar Atau Pengurangan Kadar Bagi Pegangan Yang Digunakan Semata-mata

    -
  • -
  • -

    Tanggungjawab Seorang Pembayar Cukai Taksiran

    -
  • -
-

 

-

Kadar (Cukai Taksiran atau Cukai Pintu)

-

1.0 Pengenalan

-

Kadar juga dikenali sebagai cukai taksiran atau cukai pintu adalah satu bentuk cukai yang dikenakan oleh M.B.P.P. ke atas semua pegangan dalam kawasan M.B.P.P. yang berdasarkan kepada 'Nilai Tahunan" dan 'Kadar Peratus' Tahunan. Cukai taksiran perlu dibayar dua kali setahun iaitu dalam bulan Januari dan Julai. Contoh Pengiraan Amaun Cukai Taksiran:

- - - - - - - - - - - -
-

Nilai Tahunan Pegangan

-
-

RM 3,000

-
-

Kadar Peratus Tahunan

-
-

10%

-
-

 

-

Cukai Taksiran Harta ialah RM 3,000 x 10% = RM 300 setahun atau RM 150 setiap 6 bulan

-

2.0 Nilai Tahunan

-

Nilai Tahunan sesuatu pegangan, seperti ditafsirkan dalam Seksyen 2 Akta Kerajaan Tempatan, 1976, adalah anggaran sewa tahunan pegangan itu dapat diberi sewa dengan berpatutan kepada seseorang penyewa dengan anggapan pemilik membayar kos pembaikan, insurans dan perbelanjaan lain yang perlu untuk menyenggarakan pegangan itu.

-

3.0 Kadar Peratus

-

Kadar peratus ditetapkan setiap tahun oleh Majlis mengikut keperluan kewangan. Kadar peratus yang dilulus oleh Majlis akan dikekalkan bagi sepanjang tahun dan rayuan tidak boleh dibuat terhadapnya.

-

Kadar Peratus Baru Berkuatkuasa mulai 1 Januari 2020 :

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
No.Jenis HartaKadar Baru 2020
1.Kediaman Bertanah 6.00%
2.Kediaman Bertanah Kos Rendah/Kos Sederhana Rendah5.00%
3.Rumah Pangsa Kos Rendah/Sederhana Rendah5.00%
4.Pangsapuri/Kondominium5.80%
5.Perdagangan 9.00%
6.SOHO10.00%
7.Pangsapuri Perkhidmatan10.00%
8.Industri12.00%
9.Hotel14.70%
10.Persatuan/Kongsi7.00%
11.Tanah Kemajuan - Kawasan Bandar4.00%
12.Tanah Kemajuan - Kawasan Luar Bandar2.00%
13.Tanah Pertanian0.50%
14.Kelab Golf/Kelab Lumba Kuda14.70%
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_rakyat_perkhidmatan_tempat-letak-kereta.html b/website/http___www.mbpp.gov.my__ms_rakyat_perkhidmatan_tempat-letak-kereta.html deleted file mode 100644 index 846670fd591127f003ac87af3d02acea8aa8c6ea..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_rakyat_perkhidmatan_tempat-letak-kereta.html +++ /dev/null @@ -1,1176 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Tempat Letak Kereta | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
- -
-
- - -
-
- - -
-
- - - - -
-

-
 
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file diff --git a/website/http___www.mbpp.gov.my__ms_soalan-lazim.html b/website/http___www.mbpp.gov.my__ms_soalan-lazim.html deleted file mode 100644 index 2669a820c99ef31ab133ea4e44615fff3db2ca9e..0000000000000000000000000000000000000000 --- a/website/http___www.mbpp.gov.my__ms_soalan-lazim.html +++ /dev/null @@ -1,1226 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Soalan Lazim | Portal Rasmi Majlis Bandaraya Pulau Pinang (MBPP) - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
- - -
-
- - - - - - - - -
- - - -
- -
-
- -
- - -
-
- - -
-
-
-
-
-
-
-
-
- - -
- - - -
- - - - -
-
-
-
-
-
- -
-
-
-
- - -
-
- - -
-
- - - - -
-

-

ADUAN :

-

1.Bagaimanakah cara untuk membuat aduan di MBPP?

-

 a) Aduan boleh dibuat melalui hotline MBPP 04-2637637 & 04-2637000
 b) Aduan SMS 012-4907000
 c) Portal e-Aduan (www.mbpp.gov.my)
 d) Emel ke aduan@mbpp.gov.my

-

2.Berapa lamakah tindakan akan diambil terhadap aduan yang dikemukakan?

-

 Akuan terima akan diberi pada hari yang sama.

-

3.Apakah jenis aduan yang boleh dikemukakan kepada MBPP?

-

a) Kebersihan ( sampah, parit, jalan)
b) Pemangkasan pokok
c) Kerosakan jalan
d) Pembinaan tanpa izin
e) Kemudahan awam ( lampu jalan, lampu isyarat, pondok bas, taman awam)
f) Tempat letak kereta dan lain-lain

-

CUKAI TAKSIRAN :

-

1. Apa yang dimaksudkan dengan cukai taksiran?

-

Cukai taksiran ialah cukai yang dikenakan ke atas pegangan yang terletak di dalam kawasan Majlis Bandaraya Pulau Pinang seperti rumah kediaman, harta perniagaan (kedai, komplek, hotel dsbnya), harta perindustrian (kilang, perlabuhan dsbnya) dan tanah (kosong tanpa bangunan, pertanian, tanah yang diberi kelulusan untuk tatasusunan. 

-

2. Bolehkah cukai taksiran diberi pelepasan?

-

Cukai taksiran boleh diberi pelepasan jika bangunan tersebut dirobohkan atau dimusnahkan dengan sebab-sebab kebakaran, angin ribut atau sebab-sebab lain.

-

3. Mengapa cukai taksiran dikenakan ke atas tanah oleh MBPP sedangkan ianya telah dikenakan cukai hasil oleh Pejabat Tanah?

-

Cukai tanah yang dikenakan ke atas setiap tanah menurut Kanun Tanah Negara 1966 adalah berdasarkan kepada hakmilik yang dilupuskan oleh Kerajaan Negeri mengikut peruntukan Kanun Tanah Negara 1966; sedangkan Cukai taksi ran yang dikenakan oleh MBPP adalah mengikut peruntukan di bawah Akata Kerajaan Tempatan 1976.

-

4. Adakah konsesi diberi jika sesebuah rumah tersebut diduduki oleh pemunyanya sendiri?

-

Tidak. Tidak ada sebarang peruntukan di bawah Akta Kerajaan Tempatan 1976 yang membolehkan MBPP memberi konsesi atas bayaran cukai taksiran bagi rumah yang diduduki sendiri. 

-

Senarai Nilaian Baru 2020. Klik untuk maklumat lanjut.

-

LESEN PERNIAGAAN :

-

Apakah jenis aktiviti yang memerlukan lesen Majlis ?

-
    -
  • Establisymen Makanan
  • -
  • Tred dan Perniagaan
  • -
  • Kilang
  • -
  • Rumah Urut
  • -
  • Hotel
  • -
  • kandang Lembu/Kuda
  • -
  • Memeliharaan Khinzir
  • -
  • Pasar Prebet
  • -
  • Tempat Letak Kereta
  • -
  • Iklan
  • -
  • Garaj
  • -
  • Tempat Hiburan Awam
  • -
  • Penjaja
  • -
  • Gerai Pasar, Tapak Penjaja Sementara dan Kompleks
  • -
  • Gerai Jalan Awam/Tanah Persendirian
  • -
  • Gerai Bermusim/Perayaan
  • -
  • Kenderaan Tanpa Motor
  • -
  • Lesen Anjing
  • -
  • Lesen Beca Awam
  • -
  • Lesen Pengayuh Beca Awam
  • -
-

 

-

Bagaimanakah cara memohon lesen untuk Pelbagai Tred Perniagaan ?

-

1) Dapatkan borang permohonan (borang komposit) di kaunter Bahagian Pelesenan.
2) Isikan borang dengan lengkap. Sertakan dokumen lain yang dikehendaki.
3) Kemukakan borang di kaunter Bahagian Pelesenan. Surat Akuan terima akan dihantarkan kepada pemohon.
4) Pegawai-pegawai Majlis akan membuat pemeriksaan ke atas premis berkenaan.
5) Pemohon akan dihubungi melalui surat sama ada permohonan ditolak atau diluluskan dengan syarat-syarat tertentu.

-

Bagaimana cara  memohon Lesen Gerai Penjaja ?

-

1) Dapatkan borang permohonan di kaunter Bahagian Pelesenan
  a) PK 001 untuk Penjaja
  b) PK 002 untuk Gerai

-

2) Isikan borang dengan lengkap. Sertakan dokumen lain yang dikehendaki.

-

3) Kemukakan borang di kaunter Bahagian Pelesenan Kad Akuan terima akan dikeluarkan kepada pemohon.

-

 

-

Bagaimana cara  memohon Lesen Gerai Pasar, Tapak Penjaja Sementara dan Kompleks Majlis ?

-

Pemohon akan dipanggil untuk temuduga apabila terdapat kekosongan gerai.

-

Bagaimana cara  memohon Lesen Penjaja (Statik/Beredar) ?

-

1) Pegawai-pegawai Majlis akan membuat pemeriksaan ke atas tapak lokasi/gerai berkenaan.

-

2) Pemohon akan dihubungi melalui surat berkenaan keputusan permohonan.

-

 

-

TEMPAT LETAK KERETA - SISTEM BERTIKET :

-

1. Jika saya tinggal di luar Pulau Pinang, bagaimana cara untuk saya menjelaskan bayaran tersebut?

-

Jaw: Dengan mengirim wang pos atau cek atas nama MAJLIS BANDARAYA PULAU PINANG atau MBPP.

-

2. Mengapakah notis tindakan masih dikeluarkan sedangkan kereta telah dijualkan?

-

Jaw: Tukar milik kereta masih belum dikemaskinikan oleh pihak Jabatan Pengangkutan Jalan (JPJ). 

-

3. Apa yang perlu saya lakukan sekiranya saya tidak pernah datang ke Pulau Pinang tetapi notis tindakan telah dikenakan terhadap saya?

-

Jaw: Pihak tuan hendaklah merujuk kepada nombor piring cukai yang tercatat pada notis tindakan yang dikeluarkan ke atas kenderaan tuan/ puan. Jika didapati nombor piring cukai yang dinyatakan di atas notis tindakan tersebut TIDAK SAMA dengan nombor piring cukai kenderaan anda, sila maklumkan semula kepada Majlis untuk pembatalan.

-

KOMPAUN

-

1. Saya tidak pergi ke tempat kesalahan, pada tarikh kesalahan tersebut?

-

Jaw : Berkemungkinan kenderaan tuan/puan dipinjamkan kepada ahli keluarga yang lain. Jika perkara ini masih diragui, tuan/puan diminta mengemukakan salinan geran kenderaan dan salinan piring cukai di unit 4 paras 3 Komtar untuk tindakan selanjutnya.

-

2. Saya hanya meletak kereta sekejap sahaja tetapi tetap dikenakan pemberitahu tentang kesalahan?

-

Jaw: Sila rujuk ke Bahagian Penguatkuasa untuk tindakan lanjut.

-

Sebarang pertanyaan sila hubungi:
Majlis Bandaraya Pulau Pinang,
Paras 4, KOMTAR,
Jalan Penang,
10675 Pulau Pinang

-

Tel: 04-259 2020
Fax: 04-262 6260
http://aduan.mbpp.gov.my/

- - - - - - - - - - -
Hotline: 04-2637637
: 04-2637000
-

 

-

 

-

 

-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - -
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
-
-
-
-
- - -
- -
-
- -
-
- - - - \ No newline at end of file